javascript - 如何区分使用 {} 创建的对象与使用 new 关键字创建的对象

标签 javascript

有两种创建对象的方法

  • 直接的

    变量 x={};
  • 使用 new 关键字,即使用构造函数。

    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 === Datetrue在正常情况下。由于使用构造函数创建的对象将该对象作为其原型(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/

    相关文章:

    javascript - 以 3 个字母为前缀的六位数字的正则表达式

    javascript - 基本的js验证

    javascript - 获取或发布后更改 div 显示

    javascript - 单击其他内容时如何关闭某些内容?

    javascript - jqgrid viewGridRow对话框大跨度和图标

    javascript - 发现意外的 Mach-O header 代码 : 0x72613c21 in Xcode10 with FBSDKCoreKit. 框架

    javascript - 加载新图像时显示 "loading"

    javascript - 可选的 HTTP Post 参数 JavaScript

    javascript - 如何引用 visualforce 中指定的 html 元素 id 并传递给 javascript 函数?

    javascript - 数组中的工具提示/悬停文本