在JavaScript中是否存在装箱强制?
在我读过的文章中,使用强制,您永远不会得到复杂值的结果,比如对象或数组。拳击并不被认为是精确意义上的胁迫。装箱与幕后JavaScript中的强制有什么不同?我真的看不出表面上有什么不同。这主要是语义问题 首先,让我们定义“装箱”,因为这个术语在JavaScript中并不常用(例如,规范中没有出现): “装箱”是将对象包装在基本值周围。例如,在JavaScript中是否存在装箱强制?,javascript,Javascript,在我读过的文章中,使用强制,您永远不会得到复杂值的结果,比如对象或数组。拳击并不被认为是精确意义上的胁迫。装箱与幕后JavaScript中的强制有什么不同?我真的看不出表面上有什么不同。这主要是语义问题 首先,让我们定义“装箱”,因为这个术语在JavaScript中并不常用(例如,规范中没有出现): “装箱”是将对象包装在基本值周围。例如,newnumber(42)为原语编号42创建一个Number对象 JavaScript中唯一的自动装箱是: 在基本体上使用方法时,如下所示: console.
newnumber(42)
为原语编号42创建一个Number
对象
JavaScript中唯一的自动装箱是:
console.log("testing".toUpperCase());
“testing”
是一个基本字符串,因此没有(也不能)方法。当JavaScript引擎看到具有基元根的属性访问器操作时,根据规范,它会在检索属性之前为该基元创建一个包装器对象(例如,基元字符串的String
对象)。如果正在调用属性(例如,“foo”.toUpperCase()
),则在松散模式下,包装器对象是调用中的this
(在严格模式下,它是原始字符串)。除非方法调用中的某些内容保留包装器对象,否则它将在之后被丢弃Function#call
或Function#apply
的第一个参数时,它将被装箱,以便在调用过程中此
。(在严格模式下,这个
可以是一个原语。)除非被调用的函数保留了对包装器对象的引用,否则在调用完成时它会被丢弃归根结底,重要的是,我们知道什么时候发生。我怀疑作者并没有故意对皈依和胁迫进行严格区分。拳击和胁迫是不同的事情,可以独立发生,一个或另一个,或者两者都可以
- 装箱是将基本体包装到对象中
- 强制就像将原语解释为不同的类型
'3'-1
上的强制是否与新字符串(123)
上的转换由javascript引擎的同一部分完成,但我认为这样想是正确的
您可以使用装箱来完成只能对对象执行的操作,例如:
var s = new String('a');
s.id = 123
// --> String { 0: "a", id: 123, length: 1 }
我从不需要显式地使用装箱,只需要隐式地使用装箱,例如,“abc”.charAt(0)
(意见:)
无论如何,在我的理解中,强制一词是用来强调它是隐式发生的(在其他类型的上下文中),而不是强制转换或转换。这意味着永远不会有明确的强迫!你不能真的强迫别人。强迫就这么发生了
但是强制规则可以用来强制类型,例如:''+3
实际上是一个字符串连接,但是由于隐式强制,它可以用于转换。另一方面,+'3'
或Number('3')
将是一种显式转换,而不是强制。(规范在这里似乎没有明确区分。)
因此,以一种自以为是的方式重新表述上述内容:
- 装箱是将基本体包装到对象中
- 强迫是经常发生的事,而不是你能做的事
- 转换可以显式完成,也可以利用装箱或强制
T.J.克劳德给出了正确的答案。只是补充一下,术语“装箱”在JavaScript世界中并不常用,规范也没有使用它,但它确实存在。将原语包装为对象是拳击的一种形式,YDKJS的凯尔·辛普森(Kyle Simpson)在他的演讲和书中非常清楚地指出拳击是一种隐性强迫 不幸的是,这种误解是“一切都是JavaScript中的对象”这句老话(也是不正确的)仍然屡见不鲜的部分原因。如果人们被教导原语不是对象,但JS entine可以强迫他们以拳击的形式充当对象,那么许多误解就会消失。“…像对象函数”什么是“对象函数”?可能重复@KrystianLaskowski:这是一个Java问题。这本书和问题的标签都是关于JavaScript的。@T.J.Crowder谈论装箱和拆箱,就好像它确实存在于JavaScript中一样。@sdgluck:它确实存在(
newnumber(42)
),它只是不是JavaScript通常使用的术语。
var s = new String('a');
s.id = 123
// --> String { 0: "a", id: 123, length: 1 }