#new
对于new来讲 需要注意下运算优先级
function foo(){
return this;
}
Foo.getName = function(){
console.log("1")
};
Foo.prototype.getName = function(){
console.log('2')
}
new Foo.getName();//->1
new Foo().getName(); //->2
emmm,从上面 可以看出来 new Foo() 的优先级 要大于 new Foo,所以上诉代码 可以 这样划分执行顺序
new (Foo.getName());
(new Foo()).getName();
对于第一个函数来说,先执行了Foo.getName(),所以结果 是1 队友后者来说 先执行了 new Foo() 产生了一个实例,然后通过 原型链找到了Foo 上的getName 函数,所以 结果为 2;
在new的过程中 会发生 下面4件事情
1 新生成一个对象
2 链接到原型
3 绑定this
4 返回新对象
function create(){
//创建一个空的对象
let obj = new Object();
//获得构造函数
let Con = [].shift.call(arguments)
//链接到原型
obj._proto__ = Con.prototype
//绑定this,执行构造函数
let result = Con.apply(obj,arguments)
// 确保 new 出来的是个对象
return typeof result === 'object' ? result :obj
}
对于实例对象来说,都是通过 new 产生的 无论是 function Foo() 还是 let a = {b : 1}.
对与创建一个对象来说,更推荐使用字面量的方式创建对象(无论性能上还是可读性)。因为你使用 new Object()的方式创建需要通过作用域链一层层找到object 但是你使用字面量的方式就没有这个问题
function Foo() {}
// function 就是个语法糖
// 内部等同于 new Function()
let a = { b: 1 }
// 这个字面量内部也是使用了 new Object()
·················································
function foo() {
console.log(this.a)
}
var a = 2
foo() //2
var obj = {
a: 222,
foo: foo
}
obj.foo() //222
// 以上两者的情况 ‘this’只依赖于调用函数前的对象,优先级 是第二个情况大于第一个情况。
// 以下情况是优先级最高的,`this` 只会绑定在 `c` 上,不会被任何方式修改 `this` 指向
var c = new foo()
c.a = 3
console.log(c.a)
// 还有种就是利用 call,apply,bind 改变 this,这个优先级仅次于 new
```
以上几种情况明白了,很多代码中的 `this` 应该就没什么问题了,下面让我们看看箭头函数中的 `this`
function a() {
return () => {
return () => {
console.log(this)
}
}
}
console.log(a()()())
箭头函数其实是没有 `this` 的,这个函数中的 `this` 只取决于他外面的第一个不是箭头函数的函数的 `this`。
在这个例子中,因为调用 `a` 符合前面代码中的第一个情况,所以 `this` 是 `window`。并且 `this` 一旦绑定了上下文,就不会被任何代码改变。