JavaScript:如何实现对象以使新对象({})和对象({})相同

JavaScript:如何实现对象以使新对象({})和对象({})相同,javascript,object,Javascript,Object,在JavaScript中,我可以编写: x = new Object({ a: 3 }) 我将有x={a:3} 同样,我也会写作 x = Object({ a: 3 }) 我将再次使用x={a:3} 我的问题是:Object如何实现以满足这两种调用方式?在第一个场景中,它将接收一个新的this,而在第二个场景中,它将接收全局对象 我最好的猜测是: var Object = function(obj) { var global = (function() { return this;

在JavaScript中,我可以编写:

x = new Object({ a: 3 })
我将有
x={a:3}

同样,我也会写作

x = Object({ a: 3 })
我将再次使用
x={a:3}

我的问题是:
Object
如何实现以满足这两种调用方式?在第一个场景中,它将接收一个新的
this
,而在第二个场景中,它将接收全局对象

我最好的猜测是:

var Object = function(obj) {
    var global = (function() { return this; })();
    if (global == this) { // I am called as a regular function
        // Create a copy of obj, potentially like this
        return { ...obj };
    } else { // I am called via new
        // Copy all fields of obj onto this
        // not sure what the best way to do this is.
    }
}
就这么简单

功能对象(obj){
返回obj;

}
我认为这是

function Object(obj) {
  If (this instanceof Object) {
       return Object.assign(this, ...obj)
     }
  return new Object(obj);
 }
答案是:

使用可选参数值调用对象函数时,将执行以下步骤:

  • 如果NewTarget既不是未定义的,也不是活动函数,则
    • 返回?OrdinaryCreateFromConstructor(新目标,“%ObjectPrototype%”)
  • 如果值为null未定义或未提供,则返回ObjectCreate(%ObjectPrototype%)
  • 回来!ToObject(值)
  • 步骤#1是关于当调用作为创建从
    对象继承的内容的一部分发生时,代码应该做什么,因此我们可以忽略该步骤来回答您的问题

    步骤2不适用,因为您正在传入
    ,它既不是
    null
    也不是
    未定义

    因此,第3步就是这样:它使用操作进行类型转换,将
    转换为对象。因为
    value
    已经是一个对象,所以这是一个no-op,结果就是您传入的同一个对象。
    newobject({a:1})
    newobject
    部分完全没有必要

    在第一个场景中,它将接收一个新的
    this
    ,而在第二个场景中,它将接收全局对象


    从上面的规范步骤中可以看出,
    对象
    根本不使用
    这个

    这看起来确实是你不想做的事情@Andreastorvikstrauman完全同意!我很好奇它是怎么做到的:)我明白了。出于教育目的,一切都很好。只是觉得应该提一下!我觉得即使我调用
    x=Object({a:3})
    我也会通过测试
    这个对象的实例
    ,因为
    这个
    将是全局对象。@RaduSzasz
    对象
    无论如何都是本机对象,不需要在JavaScript中实现,但是如果您感兴趣,这个技巧可以在严格模式下工作:
    function-Object(){“use-strict”;if(!this)return-Object.assign(this,…obj);…}
    。它没有那么简单,因为
    Object(1)
    是一个对象,而不是作者指定的
    1
    @user2357112,他的问题是为什么在作为类和函数执行时有两个不同的作用域。如果作者愿意,我可以尝试复制整个对象功能。我觉得有趣的是,就在你引用的部分上面,规范说“当作为构造函数调用时,它会创建一个新的普通对象。”。当我运行
    varx={};console.log(新对象(x)==x)
    我得到了
    true
    (这是我从你发布的步骤中所期望的),这似乎与我之前引用的陈述相矛盾。@Paulpro:是的,这也让我感到困惑。只有当您没有传入参数(或者传入
    null
    undefined
    )时,该语句才为真。否则,这可能是错误的。其他部分更清楚地介绍了如何将内置函数作为构造函数或函数调用(例如)。