Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/443.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在JavaScript中是否存在装箱强制?_Javascript - Fatal编程技术网

在JavaScript中是否存在装箱强制?

在JavaScript中是否存在装箱强制?,javascript,Javascript,在我读过的文章中,使用强制,您永远不会得到复杂值的结果,比如对象或数组。拳击并不被认为是精确意义上的胁迫。装箱与幕后JavaScript中的强制有什么不同?我真的看不出表面上有什么不同。这主要是语义问题 首先,让我们定义“装箱”,因为这个术语在JavaScript中并不常用(例如,规范中没有出现): “装箱”是将对象包装在基本值周围。例如,newnumber(42)为原语编号42创建一个Number对象 JavaScript中唯一的自动装箱是: 在基本体上使用方法时,如下所示: console.

在我读过的文章中,使用强制,您永远不会得到复杂值的结果,比如对象或数组。拳击并不被认为是精确意义上的胁迫。装箱与幕后JavaScript中的强制有什么不同?我真的看不出表面上有什么不同。

这主要是语义问题

首先,让我们定义“装箱”,因为这个术语在JavaScript中并不常用(例如,规范中没有出现):

“装箱”是将对象包装在基本值周围。例如,
newnumber(42)
为原语编号42创建一个
Number
对象

JavaScript中唯一的自动装箱是:

  • 在基本体上使用方法时,如下所示:

    console.log("testing".toUpperCase());
    
    “testing”
    是一个基本字符串,因此没有(也不能)方法。当JavaScript引擎看到具有基元根的属性访问器操作时,根据规范,它会在检索属性之前为该基元创建一个包装器对象(例如,基元字符串的
    String
    对象)。如果正在调用属性(例如,
    “foo”.toUpperCase()
    ),则在松散模式下,包装器对象是调用中的
    this
    (在严格模式下,它是原始字符串)。除非方法调用中的某些内容保留包装器对象,否则它将在之后被丢弃

  • 当您在松散模式下使用原语作为
    Function#call
    Function#apply
    的第一个参数时,它将被装箱,以便在调用过程中
    。(在严格模式下,
    这个
    可以是一个原语。)除非被调用的函数保留了对包装器对象的引用,否则在调用完成时它会被丢弃

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

    规范中的语言称为装箱“转换”:

    发件人:

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

    但是,它将取消装箱同时称为“转换”和“强制”:

    发件人:

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

    发件人:

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

    发件人:

    字符串对象可以强制为字符串值


    归根结底,重要的是,我们知道什么时候发生。我怀疑作者并没有故意对皈依和胁迫进行严格区分。

    拳击和胁迫是不同的事情,可以独立发生,一个或另一个,或者两者都可以

    • 装箱是将基本体包装到对象中
    • 强制就像将原语解释为不同的类型
    如果您看到装箱正在转换给定值的类型,那么这就是转换*和装箱

    e、 g:

    *)我不知道
    '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 }