- 普通函数
- 形参、实参、arguments、return、箭头函数
- 私有作用域(栈内存、执行上下文)
- 形参赋值 & 变量提升
- 作用域链
- 栈内存的释放和不释放(闭包)
- ...
- 构造函数(类)
- 类和实例
- prototype 和
__proto__ - instanceof
- constructor
- hanOwnProperty
- ...
- 普通对象
注意点
- 每一个函数(普通函数、类、内置类、Function)都是Function这个类的实例
Object.__proto__ === Function.prototype
Function.__proto__ === Function.prototype
- 所有的对象都是Object这个类的实例
- 函数也是对象(它有的属性:prototype、
__proto__、length、name ...),所以所有的函数也是Object这个类的实例
function Foo() {
getName = function () {
console.log(1)
}
return this
}
Foo.getName = function () {
console.log(2)
}
Foo.prototype.getName = function () {
console.log(3)
}
var getName = function () {
console.log(4)
}
function getName() {
console.log(5)
}
Foo.getName() //2
getName() //4
Foo().getName() //1
getName() //1
new Foo.getName() //2 new (Foo.getName)()
new Foo().getName() //3 (new Foo()).getName()
new new Foo().getName() // 3 new ((new Foo()).getName)()
关于优先级 A = B > C
A: Foo.getName
B: new Fn()
C: new Fn
所以:
new Foo.getName(): 第一步优先执行let f = Foo.getName, 第二步 new f() => new (Foo.getName)()。
new Foo().getName():优先级相等,从左向右执行 => (new Foo()).getName()。
new new Foo().getName() // 第一步先创建一个实例 let f = new Foo(), 变成new f.getName(), f.getName优先级大于 new f,所以先执行 let f2 = f.getName ,最后执行 new f2() => new ((new Foo()).getName)()