Reputation: 439
Is it possible to define a prototype only for {}-Objects?
In Javascript, almost everything is an object.
Object.prototype.test = function() {
alert("test");
}
All objects (including Number, String and Array) will have this method. But I only want this for an struct object. > {...} <
You can first create all prototypes for the object and delete it from others like Number, String and Array.
// Overwrite
Array.prototype.test = undefined; // or delete property
This "works" ... The prototype is overwritten. But the key still exists.
// Show all keys
for (key in arr)
{
alert(key); // print index of array AND keynames
}
I looking for the most elegant way to do this.
Upvotes: 5
Views: 140
Reputation: 3689
with Array.prototype.test = undefined;
you methods value sets to undefinied
, and this will not delete it.
If you realy want to delete method(property) use delete Array.prototype.test;
p.s. But in this case (with {}
object) -> you can't get what you whant with delete
.
Array.prototype
is inherited from Object.prototype
, and after deleting Array.prototype.test
your code will find Object.prototype.test
and call it.
I think the best way to make what you want is to make something like this:
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');
Upvotes: 0
Reputation: 8472
You almost certainly do not want to modify the Object
prototype. This MDN article on JavaScript inheritance sums it up nicely:
One mis-feature that is often used is to extend Object.prototype or one of the other built-in prototypes.
This technique is called monkey patching and breaks encapsulation. While used by popular frameworks such as Prototype.js, there is still no good reason for cluttering built-in types with additional non-standard functionality.
In your example, removing the test
property from Array
will not have the desired effect. When Array.test
is called, it will simply search up the prototype chain and execute Object.test
. This is illustrated by the following code:
Object.prototype.test = function () {
alert('In test');
}
delete Array.prototype.test;
//Calls Object.test and shows the alert
[].test();
Instead, you could create a base class that you control and inherit from it as needed. See below for a working demonstration.
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);
}
Upvotes: 2
Reputation: 6572
Well although you can change Object prototype, this is highly not recommended. That's because all libraries you'll ever use expect that Object is untouched. That can lead to very hard to trace bugs and unexpected behavior by some libraries.
What you need is to learn how to do correct object orientation in JS. That's a very confusing subject for js starters. I recommed you read the excelent "The Principles Of Object-Oriented JavaScript" from Nicolas Zakas and the "You don't know JS" book series from Kyle Simpson.
But you can have a good start with my explanation on how to do Object Orientation in javascript in my blog: http://www.ideasaboutcode.com/object-orientation-in-javascript/
hope it helps.
Upvotes: 0