Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS深入浅出 - 确定 this 对象指向 #6

Open
jtwang7 opened this issue May 10, 2021 · 1 comment
Open

JS深入浅出 - 确定 this 对象指向 #6

jtwang7 opened this issue May 10, 2021 · 1 comment

Comments

@jtwang7
Copy link
Owner

jtwang7 commented May 10, 2021

JS深入浅出 - 确定 this 对象指向

参考文章:
嗨,你真的懂this吗?

绑定优先级

new 绑定 > 显式绑定 > 隐式绑定 > 默认绑定

具体过程

  1. 函数是否通过 new 绑定, 若是, 则 this 绑定创建的实例对象;
  2. 函数是否通过 call, apply, bind 绑定, 若是, 则 this 绑定第一参数指定的对象;
  3. 函数是否在某个上下文对象中调用(隐式绑定), 若是, this 绑定该上下文对象, 一般是 obj.foo(), 若对象链式调用, this 指向最近的调用上下文对象;
  4. 如果以上都不是, 那么使用默认绑定; 如果在严格模式下, 则绑定到 undefined, 否则绑定到全局对象;
  • null / undefined 作为 this 的绑定对象传入 call, apply, bind 会被忽略(无效), 此时应用默认绑定规则。
  • 如果是箭头函数, 箭头函数的 this 继承的是外层词法作用域的 this,箭头函数本身没有 this 对象。
@jtwang7
Copy link
Owner Author

jtwang7 commented May 11, 2021

实战

题目:请分析并输出最后打印的结果

var number = 5;
var obj = {
    number: 3,
    fn: (function () {
        var number;
        this.number *= 2;
        number = number * 2;
        number = 3;
        return function () {
            var num = this.number;
            this.number *= 2;
            console.log(num);
            number *= 3;
            console.log(number);
        }
    })()
}
var myFun = obj.fn;
myFun.call(null);
obj.fn();
console.log(window.number);

过程分析

涉及闭包的部分,按照执行上下文的分析步骤进行解析。

  1. 脚本运行,创建全局执行上下文,此时 obj === undefined
  2. 全局执行上下文进入执行阶段,执行赋值语句修改 obj 的值,此时 (function() {...})() 被执行(默认绑定)。

注意:此时还没有执行到 var myFun = obj.fn

var number = 5;
var obj = {
    number: 3,
    fn: (function () {
        var number;
        this.number *= 2; // window.number = 10
        number = number * 2; // number === undefined
        number = 3; // number === 3
        return function () {
            var num = this.number;
            this.number *= 2;
            console.log(num);
            number *= 3;
            console.log(number);
        }
    })()
}

闭包部分分析结束,我们开始用 this 绑定规则来分析后半部分执行代码。

  1. 执行 myFun.call(null)。根据规则,显式绑定若传入参数 null 或者 undefined,实际执行默认绑定。
// this 指向 window 对象
// 闭包中,number === 3
function () {
    var num = this.number; // num === 10
    this.number *= 2; // window.number === 20
    console.log(num); 
    // 10
    number *= 3; // number === 9
    console.log(number); 
    // 9
}
  1. 执行 obj.fn()。隐式绑定 this 指向 obj 对象。
// 闭包中,number === 9
function () {
    var num = this.number; // num === 3
    this.number *= 2; // obj.number === 6
    console.log(num); 
    // 3
    number *= 3; // number === 27
    console.log(number); 
    // 27
}
  1. console.log(window.number),输出 20

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant