javascript: как переопределить метод для всех экземпляров некоторого класса?

#javascript #oop #aop

#javascript #ооп #aop

Вопрос:

 function Person(){
    this.scream = function(){
        alert('NO NO NO!!!!');
    };
}

var steve = new Person();
steve.scream() // NO NO NO!!!!
Person.prototype.scream = function(){
    alert('YES YES YES!!!!');
}
steve.scream() // still NO NO NO!!!!
  

Есть ли способ переопределить ‘scream‘ без явной ссылки на steve? Подумайте о случаях, когда у вас могут быть экземпляры Person .

Ответ №1:

НЕТ,

Имея это Person объявление, каждый раз, когда вы создаете новый его «экземпляр», будет запускаться «конструктор», и вы создадите совершенно новую scream функцию (замыкание), на которую у вас нет никаких ссылок, кроме как из вновь созданного объекта, steve.scream то есть.

В качестве альтернативы вы можете сделать это следующим образом:

 function Person(){}

Person.prototype.scream = function(){
    alert('NO NO NO!!!!');
}

var steve = new Person();
steve.scream() // NO NO NO!!!!
Person.prototype.scream = function(){
    alert('YES YES YES!!!!');
}
steve.scream() // this time is YES YES YES!!!!
  

В этом случае исходный scream «метод» доступен только в одном месте, в прототипе, и вы можете перезаписать его для всех «экземпляров».

Ответ №2:

 function Person(){};
Person.prototype.scream = function(){ alert('NO NO NO!!!!'); };
var steve = new Person();
steve.scream();
Person.prototype.scream = function(){alert('YES YES YES!!!!');};
steve.scream();
  

Ответ №3:

и, если вы хотите продолжать использовать свой стиль кода, вам может понравиться

 function Person(){
    this.constructor.prototype.scream = function(){
        alert('NO NO NO!!!!');
    };
}
var steve = new Person();
steve.scream();
Person.prototype.scream = function(){ alert('YES YES YES!!!!'); };
steve.scream();
  

Комментарии:

1. кстати, это другое, возможно, неправильное, потому что цепочка конструкторов изменит ваши прототипы

2. Кроме того, поврежден доступ к закрытию. Функция scream является общей для всех экземпляров, в то время как закрытие должно быть для каждого экземпляра.