21 javascript
在处理另一个问题时,我创造了这个小提琴:
function foo() {
// console.log(_.isBoolean(this));
console.log(this === true);
}
foo.call(true); // object:[object Boolean]
foo.apply(true); // object:[object Boolean]
Run Code Online (Sandbox Code Playgroud)
这是自动拳击的一个例子吗?
从值类型转到引用类型.
这是一个维基百科def.
Fel*_*ing 39
首先,我假设您正在讨论将原始值自动转换为对象.在JavaScript中有两种情况:
this值传递给.call或时.apply(尽管不是严格模式)."foo bar".split().在第一种情况下,转换是永久性的,即this确实将引用一个对象,在第二种情况下,转换仅在评估期间内部进行.
如果您对转换的详细信息不感兴趣,可以忽略其余的答案.
1.原始价值为 this
当一个函数被激活并且它的this值不是一个对象时,它将转换为一个,至少在非严格模式下.这在§10.4.3在ECMAScript 5.1文档中输入功能代码[spec]中描述:
当控件进入函数对象中包含的函数代码
F,提供thisArg的调用者和提供的调用者的执行上下文时,执行以下步骤argumentsList:
- 如果功能代码是严格代码,请设置
ThisBinding为thisArg.- 否则,如果
thisArg是null或undefined,则设置ThisBinding为全局对象.- 否则,如果
Type(thisArg)不是Object,请设置ThisBinding为ToObject(thisArg).
[...]
正如您在第三步中看到的那样,通过调用ToObject [spec]将值转换为对象.
2.财产准入
当您尝试访问属性时会发生类似的事情(第11.2.1节属性访问者[spec]).这里引用的部分解释了如何计算表达式foo[bar],即如何评估带括号表示法的属性访问.我们感兴趣的部分也适用于点符号.
生产
MemberExpression : MemberExpression [ Expression ]评估如下:
- 让我们
baseReference评估的结果MemberExpression.- 我们
baseValue是GetValue(baseReference).
[...]8.返回值为value 且其引用名称为,且其mode标志为的type
Reference的base值.baseValuepropertyNameStringstrictstrict
重要的一步是最后一步:无论MemberExpression评估什么,它都会转换为Reference [spec]类型的值.这是仅在规范中使用的数据类型,并包含有关如何从引用中检索实际值的其他信息(不要与实际JavaScript代码中的对象引用混淆!).
为了从这样的引用中获得"真实"值/结果,调用内部函数GetValue(V)(§8.7.1)[spec](就像上面算法中的步骤2一样),其中它表示:
当具有原始基值的属性引用时,
[[Get]]使用以下内部方法.它被称为使用其值和属性作为其参数.采取以下步骤:GetValueVbasethisP
- 我们
O是ToObject(base).
[...]
例:
假设我们有表达式
var foo = "BAR".toLowerCase();
Run Code Online (Sandbox Code Playgroud)
这是一个赋值表达式,其计算方法如下:
生产
AssignmentExpression : LeftHandSideExpression = AssignmentExpression评估如下:
- 让我们
lref评估的结果LeftHandSideExpression.- 让我们
rref评估的结果AssignmentExpression.- 我们
rval是GetValue(rref).
[...]
步骤1:评估左侧,即标识符foo.如何准确识别标识符对此并不重要.
第2步:评估右侧,即"BAR".toLowerCase().该评估的内部结果将是一个参考值,类似于:
REFERENCE = {
base: "BAR",
propertyNameString: "toLowerCase",
strict: false
}
Run Code Online (Sandbox Code Playgroud)
并存储在rref.
第3步:GetValue(rref)被叫.该base参考的是值"BAR".由于这是一个原始值,ToObject因此将调用它将其转换为临时 String对象.此外,引用实际上是属性访问,因此GetValue最终将调用对象toLowerCase上的方法String并返回方法的结果.