本文介绍了javascript autobox?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

While working on another problem, I created this fiddle:

function foo() {
    // console.log(_.isBoolean(this));
    console.log(this === true);
}

foo.call(true); // object:[object Boolean]
foo.apply(true); // object:[object Boolean]

这是自动装箱的一个例子吗?

Is this an example of auto-boxing?

从值类型转换为引用类型。

Going from a value type to a reference type.

这是

推荐答案

首先,我假设您正在讨论将原始值自动转换为对象。在两种情况下,这种情况发生在JavaScript中:

First of all I assume you are talking about automatic conversion of primitive values to objects. This happens in two cases in JavaScript:


  1. 当您将原始值作为传递时值为 .call .apply (尽管不是严格模式)。

  2. 当您尝试访问原始值的属性时,例如foo bar.split()

  1. When you pass a primitive value as the this value to .call or .apply (not in strict mode though).
  2. When you are trying to access a "property" of a primitive value, e.g. "foo bar".split().

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

In the first case the conversion is permanent, i.e. this will indeed reference an object, in the second the conversion only takes place internally for the duration of the evaluation

如果您对转换的细节不感兴趣,可以忽略其余的答案。

If you are not interested in the details of the conversion, you can ignore the rest of the answer.

1。原始值为

1. Primitive value as this

当某个函数被执行且其这个时 value不是一个对象,它被转换为一个,至少在非严格模式下。 :

When a function is exectued and its this value is not an object, it is converted to one, at least in non-strict mode. This is described in §10.4.3 Entering Function Code in the ECMAScript 5.1 documentation:


  1. 如果功能代码是严格代码,请设置 ThisBinding thisArg

  2. 否则,如果 thisArg null undefined ,将 ThisBinding 设置为全局对象。

  3. 否则,如果类型(thisArg)不是对象,请设置 ThisBinding ToObject(thisArg )。

    [...]

  1. If the function code is strict code, set the ThisBinding to thisArg.
  2. Else if thisArg is null or undefined, set the ThisBinding to the global object.
  3. Else if Type(thisArg) is not Object, set the ThisBinding to ToObject(thisArg).
    [...]


正如您在第三步中看到的那样,该值将转换为一个对象ct通过调用。

As you can see in step three the value is converted to an object by calling ToObject .

2。属性访问

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

Something similar happens when you are trying to access properties (§11.2.1 Property Accessors ). The quoted part here explains how the expression foo[bar] is evaluated, i.e. how property access with the bracket notation is evaluated. The part we are interested in applies to dot notation as well.


  1. baseReference 成为评估结果 MemberExpression

  2. baseValue GetValue(baseReference)

    [...]

  1. Let baseReference be the result of evaluating MemberExpression.
  2. Let baseValue be GetValue(baseReference).
    [...]

    8.返回类型的值,其 base 值为 baseValue 且其引用名称为 propertyNameString ,其严格模式标志为 strict

   8. Return a value of type Reference whose base value is baseValue and whose referenced name is propertyNameString, and whose strict mode flag is strict.

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

The important step is the last one: No matter to what MemberExpression evaluates, it is converted to a value of type Reference . This is a datatype only used in the specification and contains additional information about how the actual value should be retrieved from the reference (not to be confused with object references in actual JavaScript code!).

要获得此类参考的真实值/结果,内部函数被调用(就像在步骤2中一样)上面的算法),其中说:

To get the "real" value/result from such a reference, the internal function GetValue(V) (§8.7.1) is called (just like in step 2 in the above algorithm), where it says:


  1. O 成为 ToObject(base)

    [...]

  1. Let O be ToObject(base).
    [...]


示例:

假设我们有表达式

var foo = "BAR".toLowerCase();

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

This is an assignment expression which is evaluated as follows:


  1. lref 成为评估 LeftHandSideExpression 的结果。

  2. rref 成为评估 AssignmentExpression 的结果。

  3. rval GetValue(rref)

    [...]

  1. Let lref be the result of evaluating LeftHandSideExpression.
  2. Let rref be the result of evaluating AssignmentExpression.
  3. Let rval be GetValue(rref).
    [...]


步骤1:评估左侧,即标识符 foo 。如何解析确切的标识符对此并不重要。

步骤2:评估右侧,即BAR.toLowerCase()。该评估的内部结果将是一个参考值,类似于:

Step 1: The left hand side is evaluated, which is the identifier foo. How exactly identifiers are resolved is not important for this.
Step 2: The right hand side is evaluated, i.e. "BAR".toLowerCase(). The internal result of that evaluation will be a reference value, similar to:

REFERENCE = {
    base: "BAR",
    propertyNameString: "toLowerCase",
    strict: false
}

并存储在 rref

第3步:调用GetValue(rref)。引用的 base 是值BAR。由于这是一个原始值,因此将调用 ToObject 将其转换为临时 字符串对象。此外,引用实际上是属性访问,因此 GetValue 最终将调用方法 toLowerCase String 对象上并返回方法的结果。

Step 3: GetValue(rref) is called. The base of the reference is the value "BAR". Since this is a primitive value, ToObject will be called to convert it to a temporary String object. Furthermore, the reference is actually a property access, so GetValue will eventually call the method toLowerCase on the String object and return the method's result.

这篇关于javascript autobox?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-22 11:28