有两种创建对象的方法
变量 x={};
var x=新对象();
//要么
var x=新日期();//使用构造函数。
有没有办法确定该对象是如何创建的?
最佳答案
从根本上说,在 JavaScript 中,我们 不在乎 对象是如何创建的。我们通常只是假设如果对象像鸭子一样走路和像鸭子一样说话,那么它就是鸭子。 (这被称为“鸭子打字”。)事实证明也一样,因为我们不知道对象是如何创建的。
这里真的有两个问题:
{}
)还是new Object
创建的, 和 Date
)。 问题 1 的答案是:你不能。结果对象根本没有区别,因此您无法判断它是如何创建的。
问题 2 的答案更复杂:
你不能肯定地知道一个对象是用给定的构造函数创建的。 JavaScript 太强大了,让你对对象有太多的控制权,以至于无法确定。
你所能知道的只是对象的原型(prototype)链告诉你什么,你可以从中推断它是如何构造的,但推断可能是不正确的。
让我们把你的
var x = new Date();
例子。要进行这种推断,您至少可以使用三种工具:
instanceof
:例如,if (x instanceof Date)
. instanceof
是接受对象和函数的运算符。它检查对象的原型(prototype)链以查看对象是否为函数的prototype
属性指的是链中的任何地方。如果是,instanceof
的结果是 true
;如果没有,它是 false
.所以如果对象是用 new Date
创建的(或 new Foo
如果 Foo
派生自 Date
),x instanceof Date
将是真的。但同样,JavaScript 真的很强大,你可以愚弄它。例如:
var x = Object.create(Date.prototype);
console.log(x instanceof Date); // true
我们没有使用
new Date
创建那个对象,但我们不能说我们没有。 (在这种特殊情况下, x
将无法作为 Date
正常工作,因为 Date
对象具有普通对象所没有的特殊内部插槽。许多 Date.prototype
函数将在上面。但那是 Date
- 特定的。)constructor
属性(property)。默认情况下,prototype
函数的属性有一个属性,constructor
, 指向函数。例如,Date.prototype.constructor === Date
是 true
在正常情况下。由于使用构造函数创建的对象将该对象作为其原型(prototype),因此您可以使用 constructor
查看与该对象关联的构造函数(如果有):if (x.constructor === Date)
将是 true
对于使用 new Date
创建的东西(在正常情况下)。但同样,我们可以欺骗该检查:
var x = Object.create({constructor: Date});
console.log(x.constructor === Date); // true
getPrototypeOf
和相关:您可以直接检查对象的原型(prototype)链(而不是仅仅通过 instanceof
)。但这与 instanceof
具有相同的漏洞。 has:我们可以通过使用 Object.create
创建对象来欺骗它。 (或在 Object.create
之前在语言中,使用自定义构造函数)。 instanceof
具有检查整个层次结构的优点,并且不依赖于 constructor
;在使用 ES5 和更早版本创建的层次结构中(例如,在 ES2015 的 class
之前),人们经常无法设置 constructor
正确。同样,从根本上说,我们并不关心对象是如何创建的。这也很好,因为我们无法确定它是如何创建的。
关于javascript - 如何区分使用 {} 创建的对象与使用 new 关键字创建的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42732889/