javascript是否支持autobox?
在处理另一个问题时,我创建了这个小提琴: 这是自动装箱的一个例子吗 从值类型转换为引用类型javascript是否支持autobox?,javascript,Javascript,在处理另一个问题时,我创建了这个小提琴: 这是自动装箱的一个例子吗 从值类型转换为引用类型 下面是一个Javascript框,用于在非严格模式下为调用和应用提供的此参数。发件人: 如果该方法是非严格模式代码中的函数,null和undefined将被替换为全局对象,原始值将被装箱 首先,我假设您正在讨论将基本值自动转换为对象。在JavaScript中有两种情况会发生这种情况: 当您将一个基元值作为传递给时,此值将调用或。应用(但不是在严格模式下) 当您试图访问原语值的“属性”时,例如“foo b
下面是一个Javascript框,用于在非严格模式下为
调用和应用提供的此参数。发件人:
如果该方法是非严格模式代码中的函数,null
和undefined
将被替换为全局对象,原始值将被装箱
首先,我假设您正在讨论将基本值自动转换为对象。在JavaScript中有两种情况会发生这种情况:
当您将一个基元值作为传递给时,此
值将调用
或。应用
(但不是在严格模式下)
当您试图访问原语值的“属性”时,例如“foo bar”.split()
在第一种情况下,转换是永久性的,即,此
确实将引用对象,在第二种情况下,转换仅在评估期间在内部进行
如果您对转换的细节不感兴趣,您可以忽略答案的其余部分
1。原语值为此
当一个函数被执行并且它的这个值不是一个对象时,它被转换成一个对象,至少在非严格模式下是这样。ECMAScript 5.1文档中对此进行了描述:
当控件为函数对象F
中包含的函数代码、调用者提供的thisArg
和调用者提供的参数列表
输入执行上下文时,将执行以下步骤:
如果功能代码为严格代码,请将ThisBinding
设置为thisArg
否则,如果thisArg
为null
或未定义
,则将ThisBinding
设置为全局对象
否则,如果Type(thisArg)
不是Object
,则将ThisBinding
设置为ToObject(thisArg
)。
[……]
正如您在第三步中看到的,通过调用将值转换为对象
2。财产访问权
当您尝试访问属性()时,也会发生类似的情况。此处引用的部分解释了表达式foo[bar]
是如何计算的,即如何使用括号表示法计算属性访问。我们感兴趣的部分也适用于点表示法
生产MemberExpression:MemberExpression[Expression]
的计算如下:
让baseReference
作为计算MemberExpression
的结果
让baseValue
beGetValue(baseReference)
[……]
八,。返回类型为Reference
的值,其base
值为baseValue
,引用名称为propertyNameString
,其strict
模式标志为strict
重要的步骤是最后一步:无论MemberExpression
计算的是什么,它都会转换为类型为的值。这是一种仅在规范中使用的数据类型,包含有关如何从引用中检索实际值的附加信息(不要与实际JavaScript代码中的对象引用混淆!)
为了从这样一个引用中获得“真实”值/结果,调用内部函数(就像上面算法中的步骤2),其中表示:
当V
是具有基元值的属性引用时,GetValue
使用以下[[Get]]]
内部方法。使用base
作为其this
值,并使用属性P
作为其参数来调用它。采取以下步骤:
让O
beToObject(base)
[……]
示例:
假设我们有这个表达式
var foo = "BAR".toLowerCase();
这是一个赋值表达式,其计算如下:
productionAssignmentExpression:LeftHandSideExpression=AssignmentExpression
的计算如下:
让lref
作为计算LeftHandSideExpression
的结果
让rref
作为计算AssignmentExpression
的结果
让rval
beGetValue(rref)
[……]
步骤1:计算左侧,即标识符foo
。如何准确解析标识符对此并不重要。
步骤2:计算右侧,即“BAR”.toLowerCase()
。该评估的内部结果将作为参考值,类似于:
REFERENCE = {
base: "BAR",
propertyNameString: "toLowerCase",
strict: false
}
并存储在rref
中
步骤3:GetValue(rref)
被调用。参考的基
是值“BAR”
。由于这是一个基本值,因此将调用ToObject
将其转换为临时String
对象。此外,该引用实际上是一个属性访问,因此GetValue
最终将调用String
对象上的方法toLowerCase
,并返回该方法的结果。其他答案提供了有关何时发生自动装箱的详细信息,但还有几件事需要记住:
- 使用
中的
运算符时,不会发生自动装箱,如果接收到的值不是对象,则会抛出一个类型错误。一个简单的解决方案是手动用对象(值)
框住对象
当使用for…of
或允许迭代字符串的扩展语法[…value]
进行迭代时,会出现某种形式的自动装箱
REFERENCE = {
base: "BAR",
propertyNameString: "toLowerCase",
strict: false
}