【问题标题】:Why is reassigning Object.prototype not working?为什么重新分配 Object.prototype 不起作用?
【发布时间】:2010-11-12 20:16:50
【问题描述】:

为什么这不起作用?

// this one works as I expected, when objSayHello()
Object.prototype.objSayHello = function(){alert('Hello,from OBJECT prototype')};
// NOT working !
Object.prototype ={objSayHello: function(){alert('Hello,from OBJECT prototype')}};

objSayHello();

【问题讨论】:

    标签: javascript syntax function prototype object


    【解决方案1】:
    1. 因为您已经替换了 Object 原型,所以您要向从 Object 下降的任何对象(所有对象)添加 objSayHello 方法。

    2. 不要替换Object.prototype。

    你可能想要的是:

    someObj.prototype.objSayHello = function(){alert('Hello,from OBJECT prototype')};
    

    然后调用它:

    someObj.objSayHello();
    

    你的意思似乎是:

    Object.prototype.objSayHello = function(){alert('Hello,from OBJECT prototype')};
    

    但这可能是个坏主意,因为如果处理不当,它会与迭代器 (for...in) 发生冲突。

    【讨论】:

      【解决方案2】:

      Object.prototype 出于某种原因是一个 const,这意味着只读。

      【讨论】:

        【解决方案3】:
        Object.prototype.objSayHello = function(to){alert('Hello, ' + to)};
        

        上述语句意味着您将objSayHello 函数附加到将创建的所有实例,因为每个实例都是Object 的子级,因此附加的事件绑定到所有实例。例如,

        var newObject = {};
        var anotherNewObject = new Object();
        
        function person(name) {
         this.name = name;
        }
        var newPerson = new Person("Ramiz");
        
        newObject.objSayHello("newObject");
        anotherNewObject.objSayHello("anotherNewObject");
        newPerson.objSayHello(this.name);
        

        虽然,另一条语句是不正确的,并且将被完全忽略,因为您即将丢弃作为所有父对象的 prototype。如果Object 的prototype 可以被覆盖,那么所有本机实例功能都将消失。为了避免这样的错误,我认为这是忽略被覆盖。

        【讨论】:

          【解决方案4】:

          无眼是错误的,你只是can't reassign the prototypes of intrinsic types像Object,Number等。你只能追加新的属性。

          > Number.prototype
            -> Number
          > Number.prototype = {}  // Reassignment fails
            -> Object
          > Number.prototype
            -> Number
          > Number.prototype.objSayHello = 'hi'  // Appending succeeds
            -> 'hi'
          > n = new Number(); n.objSayHello
            -> 'hi'
          

          如果您使用自己的对象,则可以更新或重新分配原型(注意:重新分配原型只会影响新对象,而不影响现有对象)。

          不要更改内部原型!这是一件“坏事”,因为它会导致难以发现的副作用。如果您需要具有新属性的基本类型,则创建一个新对象,其原型指向基本对象:

          NewObject = function() {};
          NewObject.prototype = Object.prototype;
          NewObject.prototype.value = 123;
          

          现在你有一个构造函数来创建新对象,这些对象继承了它自己的原型(例如“值”)以及对象原型(“toString”、“hasOwnProperty”...)的属性。

          【讨论】:

            【解决方案5】:

            ECMAScript 语言规范有这个Object.prototype:

            Object.prototype的初始值为%Object.prototype%。

            此属性具有属性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

            对于所有其他原生 JavaScript 构造函数的 prototype 属性,您会发现相同的“[[Writable]]: false”规范,例如 Function、Number、@ 987654326@, Date, ...等

            【讨论】:

              【解决方案6】:

              Object.prototype 实际上并不是真正的原型,它只是一个参考。内部 [[prototype]] 对象用作原型,并且在某些浏览器中可以作为对象的 proto 属性访问。鉴于 JavaScript 变量的工作方式,将 Object.prototype 分配给另一个对象会更改它的引用,但不会更改内部 [[prototype]] 对象,因此您会得到一个称为原型的普通属性,它没有说明对象属性是如何解析的。

              那么,为什么在您执行 Object.prototype.myFunction() 时这会起作用? Object.prototype 仍然是对内部 [[prototype]] 的引用,因此使用此函数对其进行扩充没有问题,它与任何其他对象一样工作。

              【讨论】:

                猜你喜欢
                • 2016-04-08
                • 2012-12-06
                • 1970-01-01
                • 1970-01-01
                • 2018-02-16
                • 1970-01-01
                • 2013-03-21
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多