是否可以仅为{} -Objects定义原型?
在Javascript中,几乎所有东西都是对象。
Object.prototype.test = function() {
alert("test");
}
所有对象(包括Number,String和Array)都将使用此方法。 但我只想要这个结构对象。 > {...}<
您可以先为对象创建所有原型,然后从Number,String和Array等其他对象中删除它。
// Overwrite
Array.prototype.test = undefined; // or delete property
这“有效”......原型被覆盖。但关键仍然存在。
// Show all keys
for (key in arr)
{
alert(key); // print index of array AND keynames
}
我正在寻找最优雅的方式来做到这一点。
答案 0 :(得分:2)
您几乎肯定不想修改Object
原型。这个MDN article on JavaScript inheritance总结得很好:
经常使用的一个错误功能是扩展Object.prototype或其他内置原型之一。
这种技术称为猴子修补并打破封装。虽然像Prototype.js这样的流行框架使用了它,但仍然没有充分理由使内置类型混乱并具有额外的非标准功能。
在您的示例中,从test
删除Array
属性将无法获得所需的效果。调用Array.test
时,它只会搜索原型链并执行Object.test
。这由以下代码说明:
Object.prototype.test = function () {
alert('In test');
}
delete Array.prototype.test;
//Calls Object.test and shows the alert
[].test();
相反,您可以创建一个您根据需要控制和继承的基类。请参阅下面的工作演示。
function MyBaseClass() {
this.test = function () {
log('In test');
};
}
function Shape() {
this.shapeAction = function () {
log('Shape action');
};
}
Shape.prototype = new MyBaseClass();
function Square() {
this.squareAction = function () {
log('Square action');
this.shapeAction();
};
}
Square.prototype = new Shape();
//Test function can be called on Square, but not on Array
var s = new Square();
s.squareAction();
s.shapeAction();
s.test();
try {
[].test();
}
catch (e) {
log('Exception when trying to run Array.test: ' + e);
}
//Log function for demonstration purposes
function log(s) {
var e = document.createElement('p');
e.innerHTML = s;
document.body.appendChild(e);
}
答案 1 :(得分:0)
使用Array.prototype.test = undefined;
您将值集设置为undefinied
,这不会删除它。
如果您真的想要删除方法(属性),请使用delete Array.prototype.test;
P.S。但在这种情况下(使用{}
对象) - >你无法通过delete
得到你想要的东西。
Array.prototype
继承自Object.prototype
,删除Array.prototype.test
后,您的代码会找到Object.prototype.test
并将其调用。
我认为制作你想要的东西的最好方法是制作这样的东西:
Object.defineProperty(Object.prototype, 'test', {
enumerable: false,
configurable: false,
writable: true,
value: function(test) { alert('In test' + test); }
});
Object.defineProperty(Array.prototype, 'test', {
enumerable: false,
configurable: false,
writable: false,
value: function() { throw new Error('You can\'t do it!'); }
});
try {
var a = [];
var keys = "";
for (key in a) {
keys += key + ', '; // get all keys
}
// call array test method -> will throw exception
a.test('from array');
} catch (e) {
// check keys -> test is not here
console.log("Error: " + e.message + ' ' + "KEYS: " + keys);
}
var b = {};
// and this will work
b.test('from object');
答案 2 :(得分:0)
虽然您可以更改对象原型,但强烈建议不要这样做。这是因为您使用的所有库都希望Object不受影响。这可能导致很难跟踪某些库的错误和意外行为。
您需要学习如何在JS中正确的面向对象。对于js初学者来说,这是一个非常混乱的主题。我建议你阅读优秀的"面向对象的JavaScript的原理"来自Nicolas Zakas和"你不了解JS" Kyle Simpson的书系列。
但是,我可以在我的博客中解释如何在javascript中进行面向对象的方式:http://www.ideasaboutcode.com/object-orientation-in-javascript/
希望它有所帮助。