【问题标题】:Why would an Object prototype method override String and Number prototype methods in JavaScript?为什么 Object 原型方法会覆盖 JavaScript 中的 String 和 Number 原型方法?
【发布时间】:2016-11-07 19:00:21
【问题描述】:

尝试在Object.prototype 以及String.prototypeNumber.prototype 上定义hashCode 方法。我正在使用以下方法定义原型方法:

Object.defineProperty(Object.prototype, 'hashCode', {
  value:function() {/*code*/},
  enumerable:false
});

String.prototype.hashCode = function() {/*code*/};
Number.prototype.hashCode = function() {/*code*/};

当我使用(''new String()3new Number())中的任何一个创建数字或字符串并在实例上调用 hashCode 时,Object.prototype.hashCode 方法始终运行而不是 @ 987654334@或Number.prototype.hashCode

怎么了?

【问题讨论】:

  • 仅供参考,如果我还使用 Object.defineProperty(String.prototype... 定义字符串和数字原型方法,那么它可以按预期工作。它与使用String.prototype.hashCode = function() ... 的方式不同,这一事实让我感到困惑。
  • 将属性描述符设为writable: true,否则当在继承它的对象上写入该属性时,它将被继承为不可写。 jsfiddle.net/5ox1a0f2
  • 哦,酷。我没有意识到默认情况下它是不可写的。谢谢!
  • 对此writable行为的密切相关讨论:Does Javascript writable descriptor prevent changes on instances?
  • 确实如此。有趣的是,如果我设置 String.prototype.hashCode 和 Number.prototype.hashCode before 我调用 Object.defineProperty(Object.prorotype... 函数按预期工作,所以如果你创建它们,然后让它们不可写Object.prototype,它们已经被编写好了,不会丢失它们的值。

标签: javascript inheritance prototype-chain


【解决方案1】:

使属性描述符 writable: true 否则当在继承它的对象上写入该属性时,它将被继承为不可写。 http://jsfiddle.net/5ox1a0f2 – 眯眼

Object.defineProperty(Object.prototype, 'hashCode', {
  value:function() {console.log('object')},
  enumerable:false,
  writable:true
});

String.prototype.hashCode = function() {console.log('string')};
Number.prototype.hashCode = function() {console.log('number')};

4..hashCode()

【讨论】:

  • 注意 String.prototype.hashCodeNumber.prototype.hashCode 将是可枚举的。
  • 喜欢数字文字上的双点调用。尝试调用 '3.hashCode()' 时,我在测试中遇到语法错误,但 '3..hashCode()' 是一个不错的技巧。
【解决方案2】:

混合属性定义和属性分配可能会导致此类问题。

如果您还使用String.prototypeNumber.prototype 中的属性定义,它就可以工作:

Object.defineProperty(Object.prototype, 'hashCode', {
  value: function() {console.log('object')},
  enumerable: false
});
Object.defineProperty(String.prototype, 'hashCode', {
  value: function() {console.log('string')},
  enumerable: false
});
Object.defineProperty(Number.prototype, 'hashCode', {
  value: function() {console.log('number')},
  enumerable: false
});
(4).hashCode(); // "number"
('').hashCode(); // "string"

但是,如果你只使用属性定义是因为你不想要可枚举性,但不关心可配置性和可写性,那么通过赋值定义方法,然后重新定义可枚举性可能会更方便:

Object.prototype.hashCode = function() {console.log('object')};
String.prototype.hashCode = function() {console.log('string')};
Number.prototype.hashCode = function() {console.log('number')};
Object.defineProperty(Object.prototype, 'hashCode', {enumerable: false});
Object.defineProperty(String.prototype, 'hashCode', {enumerable: false});
Object.defineProperty(Number.prototype, 'hashCode', {enumerable: false});
(4).hashCode(); // "number"
('').hashCode(); // "string"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-15
    • 2019-11-23
    • 2021-01-26
    相关资源
    最近更新 更多