We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
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
var length = 10; function fn() { console.log(this.length); } var obj = { length: 5, method: function (fn) { fn(); arguments[0](); fn.call(obj, 12); }, }; obj.method(fn);
先来看一个函数执行,第一眼看到 fn() 的时候,直觉告诉我他是 10 ,但是冷静地瞎分析(在method函数里面执行函数,那么this应该就是执行这个函数的this)还是给出了 5 。
所以,我真的懂 this 吗。
this 是 JavaScript 的关键字之一,作为函数的特殊变量,指代函数当前的运行环境。
ECMAScript 规范中还有一种只存在于规范中的类型,它们的作用是用来描述语言底层行为逻辑。这些规范是在语言底层内部使用,作为开发我们接触不到这些类型,Reference 就其中一个类型。这里可以理解为一个interface。
我们在定义变量或者函数的时候,对应声明的变量和函数会生成对应的 Reference。Reference包括 base,propertyName,strict 三个属性,GetBase,IsPropertyReference 这两重要方法。 比如
var foo = { bar: function () { return this; } }; foo.bar(); // foo // bar对应的Reference是: BarReference = { base: foo, propertyName: 'bar', strict: false }; var foo = function () { return this; }; foo(); // bar对应的Reference是: fooReference = { base: Function Environment Record, propertyName: 'bar', strict: false };
从规范还有例子来看,一个函数的执行,其对应的 Reference 的base就是函数 Reference 的 propertyName 左边的函数执行环境,如果在执行的时候左边的变量没有定义,那么 base 就会取 Function Environment Record 这个特殊的对象。
根据规范中的描述
规范就是这么设置 this 的,ok 有了规范,那我们就可以来看下一开始那个问题了。
在执行 fn() 的时候,MemberExpression 是 foo 函数,fn Reference 的 base 是 Function Environment Record,命中第二点,返回的 this 就是 undefined,在非严格模式下,console.log(this.length); 中的 this 就指向 window 。
var value = 1; var foo = { value: 2, bar: function () { return this.value; } } //示例1: MemberExpression 是 foo.bar ,Reference 的 base 是 foo ,执行 getBase this 就是 foo console.log(foo.bar()); // 2 //示例2:同 1 console.log((foo.bar)()); // 2 //示例3: 执行了 = 运算符,表达式返回 GetValue 所以 MemberExpression 是 GetValue 的值,不是 Reference,所以 this 是 undefined console.log((foo.bar = foo.bar)()); // 1 //示例4:同 3, || 运算符也是返回的 GetValue console.log((false || foo.bar)()); // 1 //示例5:同 3, ,运算符也是返回的 GetValue console.log((foo.bar, foo.bar)()); // 1 //示例6 var _bar = foo.bar console.log(_bar()); // 1
以前总是理解 this 为调用函数的对象,虽然在很多场景下这个理解没有问题,但是看到上面的 (false || foo.bar)() 是不是就没办法解释了,所以关于 this 的具体指向,还是要从规范下手,才能最正确地解释他的指向。
The text was updated successfully, but these errors were encountered:
mqyqingfeng/Blog#7
Sorry, something went wrong.
https://juejin.cn/post/6948700444981985287
https://www.ruanyifeng.com/blog/2018/06/javascript-this.html
es5规范:http://yanhaijing.com/es5/#book
No branches or pull requests
先来看一个函数执行,第一眼看到 fn() 的时候,直觉告诉我他是 10 ,但是冷静地瞎分析(在method函数里面执行函数,那么this应该就是执行这个函数的this)还是给出了 5 。
所以,我真的懂 this 吗。
什么是 this
this 是 JavaScript 的关键字之一,作为函数的特殊变量,指代函数当前的运行环境。
js 执行底层是怎么确定这个 this 的指向的
Reference
ECMAScript 规范中还有一种只存在于规范中的类型,它们的作用是用来描述语言底层行为逻辑。这些规范是在语言底层内部使用,作为开发我们接触不到这些类型,Reference 就其中一个类型。这里可以理解为一个interface。
我们在定义变量或者函数的时候,对应声明的变量和函数会生成对应的 Reference。Reference包括 base,propertyName,strict 三个属性,GetBase,IsPropertyReference 这两重要方法。 比如
从规范还有例子来看,一个函数的执行,其对应的 Reference 的base就是函数 Reference 的 propertyName 左边的函数执行环境,如果在执行的时候左边的变量没有定义,那么 base 就会取 Function Environment Record 这个特殊的对象。
确定this的值
根据规范中的描述
规范就是这么设置 this 的,ok 有了规范,那我们就可以来看下一开始那个问题了。
在执行 fn() 的时候,MemberExpression 是 foo 函数,fn Reference 的 base 是 Function Environment Record,命中第二点,返回的 this 就是 undefined,在非严格模式下,console.log(this.length); 中的 this 就指向 window 。
总结
以前总是理解 this 为调用函数的对象,虽然在很多场景下这个理解没有问题,但是看到上面的 (false || foo.bar)() 是不是就没办法解释了,所以关于 this 的具体指向,还是要从规范下手,才能最正确地解释他的指向。
The text was updated successfully, but these errors were encountered: