【问题标题】: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】:
因为您已经替换了 Object 原型,所以您要向从 Object 下降的任何对象(所有对象)添加 objSayHello 方法。
不要替换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]] 的引用,因此使用此函数对其进行扩充没有问题,它与任何其他对象一样工作。