仅为{...}对象定义原型

时间:2015-11-09 15:30:32

标签: javascript object key prototype

是否可以仅为{} -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
}

我正在寻找最优雅的方式来做到这一点。

3 个答案:

答案 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/

希望它有所帮助。