【问题标题】:Why does adding a property to an object literal's prototype change its "type"?为什么向对象文字的原型添加属性会改变其“类型”?
【发布时间】:2013-05-01 18:04:25
【问题描述】:

所以我有一个简单的 isPlainObject 方法用于测试 JavaScript 对象字面量:

var isPlainObject = function (obj) {
  return typeof obj === "object" && {}.toString.call(obj) === "[object Object]";
};

现在我有一个普通的对象:

var obj = {'one': 1, 'two': 2, 'three': 3};

当我通过isPlainObject(obj) 函数运行它时,它按预期工作并返回true。我的问题来自向对象的原型添加属性:

obj.constructor.prototype.four = 4;

现在,当我在 obj 上运行 isPlainObject(obj) 时,它会返回 falsetypeof obj 在这两种情况下都返回 object。在我向原型添加属性后,toString 在第二个实例中返回 [object Number]

究竟发生了什么改变obj?怎么回事?

编辑: 只有在 QUnit 函数调用范围内进行测试时才会发生这种情况。

test("each", function() {

    _.each([1, 2, 3], function(i,v) {
      equal(v, i + 1, 'each iterator provided index and value from array');
    });

    var obj = {'one': 1, 'two': 2, 'three': 3};
    console.log(_.isPlainObject(obj)); // => true
    obj.constructor.prototype.four = 4;
    console.log(_.isPlainObject(obj)); // => false

});

编辑: 这是我在isPlainObject 中记录arguments 类数组对象时得到的console.log。

查看日志似乎表明该数组现在有两个参数。但长度仍为1

【问题讨论】:

  • 您使用的是什么(奇怪的)浏览器? It shows true for me...?
  • 对我来说也是如此。 typeof obj{}.toString.call(obj) 会为您返回什么?
  • 这个问题似乎表明缺乏研究工作。您的功能有几个部分;您是否调查过哪个部分的行为与您的预期不同? (typeof obj 现在是什么?{}.toString.call(obj) 现在返回什么?)
  • 你不应该修改Object.prototype! (obj.constructor.prototype 是)。不过,不确定这会如何影响您的功能。
  • 您需要为每个循环检查object.hasOwnProperty(prop)(例如types.hasOwnProperty(d),更好的是,永远不要修改 Object.prototype!(!!)(说真的!就是你为什么不这样做的原因!)投票结束过于本地化,尽管它可能与另一个“修改后的Object.prototype,现在for..in 不起作用”的问题。

标签: javascript qunit


【解决方案1】:

通过调用

({}).constructor.prototype

您正在访问所有对象的原型。所以本质上你是在为每个原生对象添加一个“四”属性。

如果你想扩展你的对象实例,你最好需要一个新的构造函数,比如:

var Count = function() {
  this.one = 1;
  this.two = 2;
  this.three = 3;
}

var obj = new Count();
obj.four = 4;

或者扩展构造函数:

Count.prototype.four = 4;

无论如何...不确定这会破坏 QUnit,但正如另一位海报所建议的那样,hasOwnProperty 应该可以解决问题。这是similar question

【讨论】:

    猜你喜欢
    • 2021-09-29
    • 2010-12-08
    • 2018-07-29
    • 1970-01-01
    • 1970-01-01
    • 2017-08-19
    • 2021-09-19
    • 1970-01-01
    • 2020-05-09
    相关资源
    最近更新 更多