从 ES 范例 中邃晓 this
本认为对 JS 中的 this 已很熟练了,再看完冴羽的博客后,才发明本身对 ES 范例知之甚少,本来我都是依据履历在推断 this,这篇文章会从最底层的 ES 范例上去引见 this 的推断。
本文已同步到个人博客从 ES 范例 中邃晓 this,谢谢勉励。
一道测试题激发的思索
第一次做这道题时,只对了第一题。。
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)());
先想一想这道题的答案,然后解释一下缘由。
范例文档
要完全弄邃晓上面的测试题,还得看范例文档 😂
罕见的几种范例:
- Reference 范例
- 函数挪用范例
- 属性读取范例
- 括号运算范例
- 赋值运算范例
- 逻辑与算法范例
- 逗号运算范例
Reference 范例
在 ECMAScript 范例中另有一种只存在于范例中的范例,它们的作用是用来形貌言语底层行动逻辑。
范例 8.7 The Reference Specification Type
Reference 范例实例大抵长如许:
var foo = { bar: function() { return this; } }; var fooReference = { base: EnvironmentRecord, name: 'foo', strict: false }; GetBase(fooReference); // EnvironmentRecord; var barReference = { base: 'foo', name: 'bar', strict: false }; GetBase(barReference); // foo;
-
GetBase(V)
. Returns the base value component of the reference V. -
HasPrimitiveBase(V)
. Returns true if the base value is a Boolean, String, or Number. -
IsPropertyReference(V)
. Returns true if either the base value is an object or HasPrimitiveBase(V) is true; otherwise returns false.
-
- If Type(V) is not Reference, return V.
- Let base be the result of calling GetBase(V).
范例 10.2.1.1.6 ImplicitThisValue()
- Return
undefined
.
- Return
函数挪用范例
-
步骤1
将 ref 赋值为 MemberExpression(简朴邃晓 MemberExpression 实在就是()左侧的部份) 步骤2
推断 ref 的范例步骤3
假如 ref 是 Reference 范例-
步骤4
假如 IsPropertyReference(ref) 是 true, 那末 this 的值为 GetBase(ref) -
步骤5
假如 base value 值是 Environment Record, 那末 this 的值为 ImplicitThisValue(ref)
-
-
步骤6
假如 ref 不是 Reference 范例,那末 this 的值为 undefined
-
提醒
非严厉形式下,this 的值为 undefined 的时刻,其值会被隐式转换为全局对象。
示例 1 解答
1、运用属性读取
范例:猎取 foo.bar
的返回范例。
2、交给函数挪用范例,去剖析 this。
-
Return a value of type Reference
whose base value is baseValue and whose referenced name is propertyNameString, and whose strict mode flag is strict. - 因而可知,属性读取,默许返回一个 Reference 范例
-
函数挪用范例
-
步骤1
->步骤2
->步骤3
->步骤4
-
示例 2 解答
1、运用属性读取
范例:猎取 foo.bar
的返回范例。
2、运用括号运算符
范例:猎取 (foo.bar)
的返回范例。
3、交给函数挪用范例,去剖析 this。
检察范例 11.1.6 The Grouping Operator
- Return the result of evaluating Expression.
This may be of type Reference
. - 实际上 () 并没有对 MemberExpression 举行盘算,所以实在跟示例 1 的结果是一样的。
- Return the result of evaluating Expression.
函数挪用范例
-
步骤1
->步骤2
->步骤3
->步骤4
-
示例 3 解答
1、运用赋值运算符
范例:猎取 foo.bar = foo.bar
的返回范例。
2、运用括号运算符
范例:猎取 (foo.bar = foo.bar)
的返回范例。
3、交给函数挪用范例,去剖析 this。
范例 11.13.1 Simple Assignment ( = )
- Let rval be
GetValue(rref)
. - Return rval. 返回的是 GetValue 后的值,不是一个 Refernce。
- Let rval be
函数挪用范例
-
步骤1
->步骤2
->步骤6
-
示例 4 解答
1、运用逻辑与算法
范例:猎取 false || foo.bar
的返回范例。
2、运用括号运算符
范例:猎取 (false || foo.bar)
的返回范例。
3、交给函数挪用范例,去剖析 this。
范例 11.11 Binary Logical Operators
- Let rval be
GetValue(rref)
. - Return rval. 返回的是 GetValue 后的值,不是一个 Refernce。
- Let rval be
函数挪用范例
-
步骤1
->步骤2
->步骤6
-
示例 5 解答
1、运用逗号操作符
范例:猎取 foo.bar, foo.bar
的返回范例。
2、运用括号运算符
范例:猎取 (foo.bar, foo.bar)
的返回范例。
3、交给函数挪用范例,去剖析 this。
- Return
GetValue(rref)
. 返回的是 GetValue 后的值,不是一个 Refernce。
- Return
函数挪用范例
-
步骤1
->步骤2
->步骤6
-
一个最一般的状况
function foo() {
console.log(this);
}
foo();
GetBase(fooReference); // EnvironmentRecord;
1、运用标识符剖析
范例:猎取 foo
的返回范例。
2、交给函数挪用范例,去剖析 this。
范例 10.3.1 Identifier Resolution
- The result of evaluating an identifier
is always a value of type Reference
with its referenced name component equal to the Identifier String.
- The result of evaluating an identifier
函数挪用范例
-
步骤1
->步骤2
->步骤3
->步骤5
-
总结
遇到题目时,只管从道理的角度对待题目,不要凭履历办事变,无妨多研讨研讨底层范例。
tip 参考资料