【问题标题】:How to differentiate object created using {} vs object created using new keyword如何区分使用 {} 创建的对象与使用 new 关键字创建的对象
【发布时间】:2017-03-11 17:34:21
【问题描述】:

创建对象有两种方式

  1. 直接

    var x={};

  2. 使用 new 关键字,即使用构造函数。

    var x=new Object(); //或者 var x=新日期(); //使用构造函数。

有没有办法确定该对象是如何创建的?

【问题讨论】:

  • 你为什么需要知道这个?
  • 因此,据我所知,javascript 中没有任何规定...如果您解释您的情况,可能有另一种方法可以解决您的问题!!..
  • 我在一些采访中被问到同样的问题
  • @ankurkushwaha 那么答案是否定的,如果你已经正确解释了面试官的问题!

标签: javascript


【解决方案1】:

从根本上说,在 JavaScript 中,我们不关心对象是如何创建的。我们通常只是假设如果对象像鸭子一样走路和像鸭子一样说话,那么它就是鸭子。 (这被称为“鸭子打字”。)事实证明也一样,因为我们无法知道对象是如何创建的。

这里真的有两个问题:

  1. 如何判断对象是使用对象初始化程序 ({}) 还是 new Object 创建的,以及

  2. 如何判断一个对象是使用这些构造函数之一还是其​​他构造函数(如Date)创建的。

问题 1 的答案是:你不能。结果对象完全没有区别,因此您无法确定它是如何创建的。

问题2的答案比较复杂:

你不能肯定地知道一个对象是用给定的构造函数创建的。 JavaScript 太强大了,让你对对象有太多的控制权,这是不可能的。

您所能知道的只是对象的原型链告诉您什么,您可以从中推断它是如何构造的,但推断可能不正确。

让我们带走你的

var x = new Date();

例子。要进行这种推断,您至少可以使用三种工具:

  1. instanceof:例如,if (x instanceof Date)instanceof 是接受对象和函数的运算符。它检查对象的原型链以查看函数的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-特定的。)

  2. constructor 属性。默认情况下,函数的prototype 属性有一个属性constructor,它指向函数。例如,Date.prototype.constructor === Date 在正常情况下是 true。由于使用构造函数创建的对象将该对象作为其原型,因此您可以使用 constructor 查看与该对象关联的构造函数(如果有):if (x.constructor === Date) 将是 true 对于使用 new Date 创建的东西(在正常情况)。

    但同样,我们可以骗过那张支票:

    var x = Object.create({constructor: Date});
    console.log(x.constructor === Date); // true
    
     
  3. getPrototypeOf 及相关:您可以直接检查对象的原型链(而不仅仅是通过instanceof)。但这与instanceof 具有相同的漏洞:我们可以通过使用Object.create 创建对象来欺骗它(或者在Object.create 出现在语言中之前,使用自定义构造函数)。

instanceof 的优点是它检查整个层次结构,并且不依赖于constructor;在使用 ES5 及更早版本创建的层次结构中(例如,在 ES2015 的 class 之前),人们经常无法正确设置 constructor

同样,从根本上说,我们并不关心对象是如何创建的;这也很好,因为我们无法确定它是如何创建的。

【讨论】:

  • 对,但它不仅仅是日期,它可以是 Blob,它可以是任何自定义构造函数。如何创建通用检查
  • @ankurkushwaha:嗯,instanceofconstructor 通用检查。我也进行了一些更新以对此进行扩展。基本上,在 JavaScript 中,我们并不关心对象是如何创建的。
【解决方案2】:

你无法区分普通对象的创建,因为对于 javascript 这完全一样。

var o1 = {};
var o2 = new Object();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 2019-01-17
    • 2023-04-05
    • 2016-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多