Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Define prototype for {...} objects only

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.

like image 306
Dominik Avatar asked Oct 30 '22 16:10

Dominik


1 Answers

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);
}
like image 173
Drew Gaynor Avatar answered Nov 09 '22 06:11

Drew Gaynor