javascript autobox?

21 javascript

在处理另一个问题时,我创造了这个小提琴:

http://jsfiddle.net/tr2by/

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中有两种情况:

  1. 将原始值作为this值传递给.call或时.apply(尽管不是严格模式).
  2. 当您尝试访问原始值的"属性"时,例如"foo bar".split().

在第一种情况下,转换是永久性的,即this确实将引用一个对象,在第二种情况下,转换仅在评估期间内部进行.

如果您对转换的详细信息不感兴趣,可以忽略其余的答案.


1.原始价值为 this

当一个函数被激活并且它的this值不是一个对象时,它将转换为一个,至少在非严格模式下.这在§10.4.3在ECMAScript 5.1文档中输入功能代码[spec]中描述:

当控件进入函数对象中包含的函数代码F,提供thisArg的调用者和提供的调用者的执行上下文时,执行以下步骤argumentsList:

  1. 如果功能代码是严格代码,请设置ThisBindingthisArg.
  2. 否则,如果thisArgnullundefined,则设置ThisBinding为全局对象.
  3. 否则,如果Type(thisArg)不是Object,请设置ThisBindingToObject(thisArg).
    [...]

正如您在第三步中看到的那样,通过调用ToObject [spec]将值转换为对象.

2.财产准入

当您尝试访问属性时会发生类似的事情(第11.2.1节属性访问者[spec]).这里引用的部分解释了如何计算表达式foo[bar],即如何评估带括号表示法的属性访问.我们感兴趣的部分也适用于点符号.

生产MemberExpression : MemberExpression [ Expression ]评估如下:

  1. 让我们baseReference评估的结果MemberExpression.
  2. 我们baseValueGetValue(baseReference).
    [...]

   8.返回值为value 且其引用名称为,且其mode标志为的type Referencebase值.baseValuepropertyNameStringstrictstrict

重要的一步是最后一步:无论MemberExpression评估什么,它都会转换为Reference [spec]类型的值.这是仅在规范中使用的数据类型,并包含有关如何从引用中检索实际值的其他信息(不要与实际JavaScript代码中的对象引用混淆!).

为了从这样的引用中获得"真实"值/结果,调用内部函数GetValue(V)(§8.7.1)[spec](就像上面算法中的步骤2一样),其中它表示:

当具有原始基值的属性引用时,[[Get]]使用以下内部方法.它被称为使用其值和属性作为其参数.采取以下步骤:GetValueVbasethisP

  1. 我们OToObject(base).
    [...]

例:

假设我们有表达式

var foo = "BAR".toLowerCase();
Run Code Online (Sandbox Code Playgroud)

这是一个赋值表达式,其计算方法如下:

生产AssignmentExpression : LeftHandSideExpression = AssignmentExpression评估如下:

  1. 让我们lref评估的结果LeftHandSideExpression.
  2. 让我们rref评估的结果AssignmentExpression.
  3. 我们rvalGetValue(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并返回方法的结果.


aps*_*ers 5

Javascript框this提供的参数callapply非严格模式.来自MDN:

如果该方法是在非严格模式代码的功能,nullundefined将与全局对象来代替,而原始的值将被装箱.