1
votes

Helloworld,

I want to create a prototype of array.

Array.prototype.foo = function(){}

But my prototype must apply only if this array contain only a specific object like "bar" Is it possible to create a prototype like this in javascript? :

Array<bar>.prototype.foo = function(){}

Thank you! James

4
There seems to be a confusion in the terms here, maybe on your mind too, so: on this line Array.prototype.foo = function(){}; you are not creating a prototype of array. You are extending the existing Array prototype with a new property (which can be a bad idea). Can you explain with more precisions what you want to do? By the way, Javascript is not a typed language, so the second line is not possible - Kaddath
You need to expand your question by providing a use case and desired behaviour. - Yury Tarabanko
Not only is it unclear what you are trying to accomplish, you are asking about modifying a javascript internal, which has some serious consequences for your app. It feels like this is an XY Question, and you are asking about your solution (add a prototype to Array) rather than asking about whatever problem it is that you are trying to solve by making this drastic change. Perhaps if you ask about the problem instead, people can help you solve that. - Claies

4 Answers

2
votes

No, you can not.

You can check for the types in your current array.

class Bar {}

Array.prototype.foo = function() {
  if (this.some((n) => !(n instanceof Bar))) throw new Error('Incompatible type.');
  
  console.log('called');
}

let array = [1, 2];
try {
  array.foo();
} catch(e) {
  console.log(e.message);
}

array = [new Bar(), new Bar()];
array.foo();
1
votes

One way to do this would be to check if your array contains bar before doing anything else, and stopping if it does not :

    Array.prototype.foo = function(){
    	if (this.indexOf('bar') === -1) {
    		throw "The array must contain bar";
    	}
    	// do what must be done
      console.log("all good");
    }
    
    var rightOne = ['john', 'jane', 'bar'];
    var wrongOne = ['john', 'jane'];
    
    rightOne.foo();
    wrongOne.foo();
    
0
votes

I think that you can do something similar. The best way that I can think to do is it to decorate the default JavaScript array with an additional function. Below is an example showing a print function working.

let test = ['a', 'b', 'c'];

function decoratedArray(args) {
  let decorated = [...args];
  decorated.print = () => {
    decorated.forEach((arg) => {
      console.log(arg);
    });
  }
  
  return decorated;
}

test = decoratedArray(test);

test.print();
0
votes

With ES6 classes you could subclass an Array to get all it's internal methods, and add your own methods to it without modifying the native Array prototype.

class Bar {
  constructor(id) {
    this.id = id
  }
}
  
class Foo extends Array {
  constructor(...args) {
    super(...args)
  }
  foo() {
    if (this.some(x => x instanceof Bar === false))
      throw new Error('Foo can only contain Bar instances')
    console.log('All items are Bars')
    return this
  }
}

const pass = new Foo(new Bar(1), new Bar(2))
const fail = new Foo(new Bar(3), new Object)

pass.foo()
fail.foo()