JavaScript中的拳击强制吗? [英] Is boxing coercion in JavaScript?

查看:31
本文介绍了JavaScript中的拳击强制吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

You Don中我不知道JS-强制性章节我已经读过,使用强制性,您永远不会得到像对象或数组之类的复杂值的结果.从准确的意义上讲,拳击没有被认为是强制性的.拳击与引擎盖背后的JavaScript强制有何不同?我真的看不出表面有任何区别.

In You Don't Know JS - the Coercion Chapter I've read that with coercion, you never get result that is a complex value, like object or an array. Boxing wasn't considered coercion in an accurate sense. How is boxing different from coercion in JavaScript behind the hood? I really can't see any difference on the surface.

推荐答案

这在很大程度上是语义问题.

This is largely a matter of semantics.

首先,让我们定义装箱",因为该术语在JavaScript中并不常用(例如,它未出现在规范中):

First, let's define "boxing," since the term isn't commonly used in JavaScript (it doesn't appear in the spec, for instance):

装箱"将对象包装在原始值周围.例如, new Number(42)为原始数字42创建一个 Number 对象.

"Boxing" is wrapping an object around a primitive value. For instance, new Number(42) creates a Number object for the primitive number 42.

使用JavaScript完成的唯一自动装箱操作是:

The only automatic boxing done in JavaScript is:

  1. 在基元上使用方法时,如下所示:

  1. When you use a method on a primitive, like this:

console.log("testing".toUpperCase());

测试" 是原始字符串,因此没有(也没有)方法.当JavaScript引擎看到带有原始根的属性访问器操作时,根据规范,它会在检索该属性之前为该原始创建包装对象(例如,原始字符串的 String 对象).如果正在调用该属性(例如,"foo" .toUpperCase()),则在松散模式下,包装对象在调用内是 this (在严格模式下,它是原始对象细绳).除非方法调用中的某些内容保留了包装对象,否则它将被丢弃.

"testing" is a primitive string, and thus doesn't (and can't) have methods. When the JavaScript engine sees a property accessor operation with a primitive root, per spec it creates a wrapper object for that primitive (a String object for a primitive string, for instance) before retrieving the property. If the property is being called (e.g., "foo".toUpperCase()), in loose mode the wrapper object is this within the call (in strict mode it's the primitive string). Unless something within the method call retains the wrapper object, it's thrown away afterward.

在松散模式下将原语用作 Function#call Function#apply 的第一个参数时,将其装箱以便成为在通话过程中.(在严格模式下, this 可以是原始类型.)除非被调用的函数保留对包装对象的引用,否则在调用完成时将其丢弃.

When you use a primitive as the first argument to Function#call or Function#apply in loose mode, it's boxed in order to be this during the call. (In strict mode, this can be a primitive.) Unless the function being called retains a reference to the wrapper object, it's thrown away when the call is done.

取消装箱当然是相反的:从装箱对象中获取原语.

Unboxing is, of course, the converse: Getting the primitive from the boxing object.

规范中的语言称拳击转换":

The language in the specification calls boxing "conversion":

来自§7.1.13:

抽象操作ToObject 参数转换为Object类型的值...

The abstract operation ToObject converts argument to a value of type Object...

但是,它称​​拆箱为转换"和强制":

However, it calls unboxing both "conversion" and "coercion":

来自§7.1.1:

抽象操作ToPrimitive 将其输入参数转换为非对象类型

The abstract operation ToPrimitive converts its input argument to a non-Object type

来自§4.3.16:

布尔对象可以强制为布尔值.

来自§4.3.19:

可以将String对象强制为字符串值...

最终,重要的是我们了解何时会发生什么.我怀疑作者没有故意对 convert coerce 进行强力区分.

At the end of the day, what matters is that we understand what happens when. I suspect that a strong distinction between convert and coerce has not intentionally been made by the authors.

这篇关于JavaScript中的拳击强制吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆