JavaScript确定this的指向

本文详细探讨了JavaScript中this的指向确定,包括通过Reference理解this的归属,new操作符的影响,以及各种情况下的示例分析,如成员表达式、赋值操作、逻辑运算和逗号表达式对this指向的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

this的指向确定

  • 参考说明
  • Reference介绍
  • this确定的方法
  • new的说明
  • 样例

1. 参考说明

拜读了冴羽大神的深入系列,然后加上自己谷歌的一些理解,让这部分更加容易理解

冴羽大神深入系列

new操作符理解诶

例子

2. Reference介绍

利用Reference 来就是用来解释诸如 delete、typeof 以及赋值等操作行为的。用其更好的描述语言的底层行为

几个概念

对于任何一个我们需要查询的属性,我们将其Reference 用三部分来组成

  1. base value

代表的是该属性所在的对象, 其值为Object, boolean, string, number, environment record(环境)

  1. reference name

代表的是该属性的名称

3.strict reference

代表的是否为严格模式

  1. GetBase()方法

用来获取base value的值

  1. isPropertyReference()

当base value是一个对象就返回true (我们在这里用来判断this的归属)

6.GetValue

无论任何操作我们取到Reference实际对应的值,调用的全都是GetValue方法, 而只要调用的是GetValue方法,我们获得的一定是一个确定的值,不再是一个Refference (之后做判断!!!重要)

3. this确定的方法

  1. 求出MemberExpression对应的Reference对象 (如果可以的话)

这里的MemberExpression就是我们查询这个属性时候的表达式

例子:

    var foo = 1;
    
    var fooReference = {
        base: EnvironmentRecord,
        name: 'foo',
        strict: false
    };

foo定义在全局中所以 对应的base我们认为base=Environment 或者认为是window也可以,其余的不用介绍了把~

  1. 判断 ref 是不是一个 Reference 类型

2.1 如果 ref 是 Reference,并且 IsPropertyReference(ref) 是 true, 那么 this 的值为 GetBase(ref)

2.2 如果 ref 是 Reference,并且 base value 值是 Environment Record, 那么this的值为 ImplicitThisValue(ref)

2.3 如果 ref 不是 Reference,那么 this 的值为 undefined

4 new 的说明

new在创建一个对象时,其伪代码可以写为

new A("p1"){
    var o = {};
    o.__proto__ = A.prototype;
    result = A.call(o, "p1");
    
    result = typeof result === "object"? result: o;
    
    return result
    
}

所以如果我们定义的构造函数如果存在返回值,返回值的情况不同会导致我们 base value的不同

    // Example 1
    function Person(name){
        this.name = name;
        return 1
    }
    
    person = new Person("tom");
    
    console.log(person.name) // "tom"
    
    // Example 2
    
    function Person2(name){
        this.name = name;
        return {}
    }
    
    person2 = new Person2("tom");
    console.log(person2.name) // undefined

Example 1: 确定person.name, base value = person, 此时的person来自于new Person() 由于返回值是1不是对象,所以返回obj(详见上述的new的详细解释), 因此base value = Person(), 用isPropertyReference()得到true, 所以此时的this指向就是person 输出为tom (见上述的判断方法)

Example 2: 由于 person2.name中的person来自于 new Person2()返回的{}. 同1理, 这里this指向为{}, 里面不存在name属性, 所以为undefined

例子:

    var value = 1;
    
    var foo = {
      value: 2,
      bar: function () {
        return this.value;
      }
    }
    
    //例1
    console.log(foo.bar());
    //例2
    console.log((foo.bar)());
    //例3
    console.log((foo.bar = foo.bar)());
    //例4
    console.log((false || foo.bar)());
    //例5
    console.log((foo.bar, foo.bar)());

例1

找到foo.bar为MemberExpression, 其可转化为Reference, ref为

{
    baseValue: foo, 
    name: bar
}

其baseValue 对应着一个object对象,所以其this指向就是foo 输出为 2

例2

(foo.bar)() 和 foo.bar 相同,因为()仅改变运算顺序,而本身的运算顺序就是从左到右不改变,所以和第一题一样,输出为2

例3

这里先进行了 foo.bar = foo.bar

MemberExpression简化成 ref() 其中ref = (foo.bar = foo.bar) 我们需要判断ref中this 的指向

  1. 首先: "="是一个赋值操作, 赋值操作返回的是一个值 (利用GetValue方法), 不再是一个Reference 对象了

  2. 此时ref返回不再是一个Reference, 所以此时将this指向 undefiend, 非严格模式下, undefiend就是指向window

  3. 最终输出 1

例4

MemberExpression简化成 ref() 其中ref = (false || foo.bar) 我们需要判断ref中this 的指向

false || foo.bar 这里相当于进行了一个赋值操作 调用了GetValue方法 和例3一样, this指向window 输出1

例5

在大神博客中讲, 官方的说明中写出 逗号表达式也是反映为GetValue, 因此输出仍为1

(A, B)() —> 先执行A, 再执行B, 之后把B 的函数进行调用输出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值