对象
对象字面量
const obj = {}
对象原型
Object.create = function(obj) {
const F = new Function()
F.prototype = obj
return new F()
}
对象值的检索路线
- 现在对象内部进行查找
- 如果对象内部没有改值,则去往对象的
__proto__
内递归查找
反射
- 检索对象并确定对象属性类型:
typeof
const flight = {
number: 'A1389',
status: 'Online',
arrival: 'HZ'
}
typeof flight.number // 'number'
typeof flight.status // 'string'
- 注意原型链中的属性也会产生值
typeof flight.toString // 'function'
typeof flight.constructor // 'function'
函数
1. 函数对象
- 函数也是对象,也可以在其上挂载键值
- 每个函数在创建出来的时候会附加两个隐藏属性:函数上下文、实现函数行为的代码(调用属性)
function a() {}
a.test = 888
console.log(a.test) // 888
2. 调用
- 方法调用 - 函数被保存为对象属性时 -
obj.func()
- 函数调用 - 直接调用函数 -
func()
- 构造器调用 - 函数为构造函数时-
new Cat()
- apply调用 -
func.apply(context, [参数])
- call调用 -
func.call(context, 参数, 参数, 参数)
3. 返回
- 未指定返回值返回undefined
- 构造器调用返回this
4. 闭包
- 定义:外层函数嵌套内层函数,内层函数访问外层函数设置的变量,形成闭包
const addTo = (num) => {
return (num2) => {
return num + num2
}
}
const addTo5 = addTo(5)
console.log(addTo5(3)) // 8
- 避免在循环中创建函数
// 糟糕的例子
function addClick(nodes) {
for (var i = 0; i < 10; i++) {
nodes[i].addEventListener('click',function() {
console.log(i)
})
}
}
// 当然了,用let能解决问题。但还是不推荐这样写
5. 模块模式:定义私有变量和函数,利用闭包创建可访问私有变量和函数的特权函数并将这些特权函数暴露出来
const Util = (() => {
const log = (msg) => { console.log(msg) }
return {
add: (a, b) => {
log('add!!')
return a + b
},
sub: (a, b) => {
log('sub!!')
return a - b
}
}
})()
Util.add(1, 2) // 'add!!' 3
6. 函数缓存
// 简单版,未考虑context变化,直接改变函数变量
const memory = (func) => {
const result = {}
return (...args) => {
const key = [].slice.call(args).join(',')
if (result[key]) {
return result[key]
} else {
const retValue = func.apply(this, args)
result[key] = retValue
return retValue
}
}
}
let fib = (n) => {
return n < 2 ? n : fib(n - 1) + fib(n - 2)
}
fib = memory(fib)
继承
1. 构造器创建对象 - 自己写构造器方法
// 写法1
Function.prototype.myNew = function() {
const that = Object.create(this.prototype)
const other = this.apply(that, arguments)
return typeof other === 'object' ? other : that
}
// 写法2
const myNew = function(_constructor, ...args) {
const obj = {}
const result = _constructor.apply(obj, args)
obj.__proto__ = _constructor.protortpe
return typeof result === 'object' ? result : obj
}