this指向的相关问题

114 阅读2分钟

1 new 的实现原理

1.创建一个空对象,构造函数中的this指向这个空对象

2.这个新对象.proto = 构造函数.prototype

3.执行构造函数方法,属性和方法被添加到this指向的对象中

4.如果构造函数中没有返回其它对象,那么返回this,即创建的这个的新对象,否则,返回构造函数中返回的对象

function myNew() {
    let target = {}
    // constructor构造函数
    let [constructor, ...args] = [...arguments];
    // 原型链关联
    target.__proto__ = constructor.prototype;
    // 执行构造函数,将属性或者方法添加到target
    let result = constructor.apply(target, args);
    // 返回值得类型
    if(result && (typeof (result) === 'object' || typeof (result) === 'function')){
        return result;
    }
    // 如果构造函数返回值不是引用类型,而是基本类型 返回新对象
    return target;
}

2.this的指向确认

> 优先级   属性访问.   >  new foo()  >  foo()

总结:谁调用它,this 就指向谁

细分:

1.全局环境中的 this:

    浏览器环境:无论是否在严格模式下,在全局执行环境中(在任何函数体外部)this 都指向全局对象 window;
    node 环境:无论是否在严格模式下,在全局执行环境中(在任何函数体外部),this 都是空对象 {};

2.是否是 new 绑定:

如果构造函数中没有返回 function 或者是 object,那么 this 指向这个新对象。

```js
function Person(age){
    this.age = age
}
let instance = new Person('20')
console.log(instance) // 20
```

构造函数返回值是 function 或 object, new Person()是返回的是Person的返回值

```js
function Person(age){
    this.age = age
    return {
        a: 2
    }
}
let instance = new Person('20')
console.log(instance) // {a:2}
console.log(instance.age) // undefined
```

3.函数通过 call、apply 调用,或者 bind 绑定,那么this绑定的就是指定的对象【归结为显式绑定】。 >特殊情况: 如果 call,apply 或者 bind 的第一个参数值为 undefined 或者 null,严格模式下 this 的值为传入的值 null /undefined。非严格模式下,实际应用的默认绑定规则,this 指向全局对象(node环境为global,浏览器环境为window)

4.箭头函数:继承箭头函数外层上下文绑定的this