【问题标题】:How to write prototype function for object in javascript?如何在javascript中为对象编写原型函数?
【发布时间】:2017-08-11 07:57:20
【问题描述】:

有可能做这样的事情吗?

let foo = {}, bar = {name : "carl"};
foo.isNotEmpty && "foo is not empty" // FALSE
bar.isNotEmpty && "bar is not empty"; // TRUE


Object.prototype.isNotEmpty = function (){
 return Object.keys(_argument_here).length == 0;
}

我不知道如何在我的原型方法中使用对象(在本例中为 foo 和 bar)。我也想像属性而不是函数一样使用它,否则它看起来像这样

foo.isNotEmpty() && "foo is not empty"

我更喜欢第一种方式,但如果不可能,第二种方式也可以。 感谢您的帮助。

【问题讨论】:

  • 我注意到您现在已经问了几个问题,但没有接受任何答案。接受答案,当他们值得接受时,会将该问题从未回答的问题列表中删除,并将该答案移至列表顶部。更多:What should I do when someone answers my question?

标签: javascript object prototype


【解决方案1】:

我不知道如何在我的原型方法中使用对象(在本例中为 foo 和 bar)。

你会在函数中使用this

但是

  1. 永远,永远,永远Object.prototype 添加可枚举属性(Object.prototype.isNotEmpty = ... 就是这样做的)。您将破坏大量假设{} 上的for-in 不会看到任何要访问的属性/Object.keys({}) 将返回一个空数组的代码。如果你真的想这样做,使用Object.defineProperty,不要将enumerable设置为true(默认是false,所以如果你不使用它就可以了)。

  2. 通常强烈建议不要向 Object.prototype 添加不可枚举的属性,因为这可能与对象的预期“自己”属性发生冲突。

  3. 您需要在调用它之前添加它。在您的代码中,您尝试在添加之前访问它。

  4. 要在不使用 () 的情况下获得所需的结果,您需要将函数定义为属性 getter(更多内容见下文)。

所以你可以这样做(使用非 getter 函数):

Object.defineProperty(Object.prototype, "isNotEmpty", {
    value: function (){
        return Object.keys(this).length == 0;
    },
    configurable: true
});

let foo = {}, bar = {name : "carl"};
console.log(foo.isNotEmpty());
console.log(bar.isNotEmpty());

...或者如果你想要一个吸气剂:

Object.defineProperty(Object.prototype, "isNotEmpty", {
    get: function (){
        return Object.keys(this).length == 0;
    },
    configurable: true
});

let foo = {}, bar = {name : "carl"};
console.log(foo.isNotEmpty);
console.log(bar.isNotEmpty);

但是通常最好有自己的函数(在范围构造内 [未显示],因此您没有定义全局):

function isNotEmpty(obj) {
    return Object.keys(obj).length == 0;
}

let foo = {}, bar = {name : "carl"};
console.log(isNotEmpty(foo));
console.log(isNotEmpty(bar));

【讨论】:

  • 感谢您的提示,我认为如果我可以定义一个检查对象是否为空的辅助函数会更好,对吧?
  • @Nezih:是的。另请注意,Object.keys 仅检查 enumerableown 属性。因此,如果您正在检查的对象具有任何不可枚举的自身属性,那么您仍然会认为它是空的。
  • 根据 Kanstantsin Kamkou 的回答。它工作得很好。你怎么看?
  • @Nezih:我认为这个答案是错误的,因为像您正在使用的对象这样的通用对象没有length 属性。 (但这就是我在上面的回答中关于“吸气剂”的意思。)我请您参考上面的两个工作示例。另外:在我之前的评论中,我忘了指出一个函数:Object.getOwnPropertyNames。这为您提供了 Object.keys 为您提供的 plus “自己的”不可枚举属性,只要它们是字符串。 (如果你有以符号命名的属性,你还需要Object.getOwnPropertySymbols。)
【解决方案2】:
Object.defineProperty(
  Object.prototype, 'isNotEmpty', {
   get: function() {
     return this.length > 0;
   }
  }
);

const a = 'test';
console.log(a.isNotEmpty); // true

如前所述,javascript是一门陌生的语言,请不要污染原型。

【讨论】:

  • 这就是我所说的。谢谢。
  • 通用对象(例如 OP 问题中的对象)没有 length 属性。
  • 你有奇怪的cmets。首先,js 没有泛型对象。 js中的对象......也不是对象。污染原型假设以某种方式检测类型,例如:_.isString(this) 或 Array.isArray() 等等。
  • @KanstantsinKamkou:{} 通常被称为通用对象(与new Date 或类似的结果相反)。再说一遍:他们没有length。如果你真的运行上面的代码和 OP 的例子,你会发现它不起作用。与其将评论称为奇怪和挑剔的术语,不如真正注意它所说的要点。 (恐怕你评论的整个后半部分[“污染”向前]在英语中完全不清楚。)
  • 普通对象(可能就是你所说的generic object)是那些没有原型或原型为空的对象。即Object.getPrototypeOf(new Date())Object.getPrototypeOf({})。你提到的事情我不熟悉。对不起。我不想继续这个话题。谢谢。
猜你喜欢
  • 1970-01-01
  • 2018-01-19
  • 1970-01-01
  • 2017-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-06
  • 1970-01-01
相关资源
最近更新 更多