Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   как обратиться к родному методу конструктора, после его переопределения (https://javascript.ru/forum/misc/54988-kak-obratitsya-k-rodnomu-metodu-konstruktora-posle-ego-pereopredeleniya.html)

jesteross 09.04.2015 00:36

как обратиться к родному методу конструктора, после его переопределения
 
Не знаю насколько правильно задал вопрос, буду благодарен любой помощи, и возможно ещё каким-то человеческим объяснениям наследования в js :)

function Animal(obj){
	this.name = obj.name;
	this.age = obj.age;
	this.al = function(){
		alert(this.name + ' живут ' + this.age + ' лет');
	}
}

var dog = new Animal({name:'dog', age: 15});
dog.al(); // dog живут 15 лет
dog.al = function(){
	alert(this.name + ' живут ' + (this.age+10) + ' лет');
}
dog.al(); // dog живут 25 лет


код здесь http://jsfiddle.net/upxtw8j6/3/

можно ли как то вызвать родной метод al() из Animal, не создавая нового объекта new Animal? то есть что бы опять вывелось 15 лет.

Vlasenko Fedor 09.04.2015 01:31

function Animal(obj){
	this.name = obj.name;
	this.age = obj.age;
	this.al = function(){
		alert(this.name + ' живут ' + this.age + ' лет');
	}
}

var dog = new Animal({name:'dog', age: 15});
dog.al();
var me = dog.al;
dog.al = function(){
	alert(this.name + ' живут ' + (this.age+10) + ' лет');
}
dog.al();
me.apply(dog);
:)

MallSerg 09.04.2015 01:41

Тебе не понятно что происходит в конструкторе по этому ты задаешь такой вопрос.
this.name, this.age, this.al - это просто переменные которые создаются при вызове конструктора если ты из изменишь то естественно не сможешь обратится к их старому значению.

jesteross 09.04.2015 01:42

var me = dog.al;

Спасибо, хороший вариант, но я думал может есть какой-то вариант обратится через прототип, конструктор или ещё как-то...

Кстати может изначально я должен был метод по другому переопределять?

jesteross 09.04.2015 01:45

Цитата:

Сообщение от MallSerg
this.name, this.age, this.al - это просто переменные которые создаются при вызове конструктора если ты из изменишь то естественно не сможешь обратится к их старому значению.

Да приблизительно так и понимаю... :)
Но может можно как-то вытащить родной метод из конструктора?

MallSerg 09.04.2015 02:05

Конструктор это просто функция которая возвращает объект и ничего больше в принципе невозможно получить какую то ее часть. зато ты можешь делать со свойствами построенного(сконструиров нного) объекта все что хочешь. даже сохранить эти свойства в отдельные переменные.

Кстати наличие функции в конструкторе будет приводить к замыканию при каждом вызове конструктора.

jesteross 09.04.2015 02:43

Спасибо за хорошее объяснение.

Цитата:

Сообщение от MallSerg
Кстати наличие функции в конструкторе будет приводить к замыканию при каждом вызове конструктора.

Что такое замыкания приблизительно себе представляю,
но тут я не пойму, что именно будет в этом замыкании, и плохо это или хорошо? на что влияет?

Может у вас как у опытного специалиста есть простые правила, когда замыкание появляется, и как его избежать, или наоборот использовать в мирных целях...

Мне вот например понравилось:
"|| запинается на «правде»,
&& запинается на «лжи»."
Было бы что-то такое про замыкания, было бы хорошо :)

theKingOfJava 09.04.2015 05:58

Цитата:

Сообщение от jesteross
может есть какой-то вариант обратится через прототип

Конечно есть. Только надо дефолтные значения задать, иначе, значения будут undefined:
function Animal(obj){
    this.name = obj.name;
    this.age = obj.age;
}

Animal.prototype={
 age: 0,
 name: "noname",
 al: function(){
   alert(this.name + ' lives ' + this.age + ' years');
 }
}
 
var dog = new Animal({name:'dog', age: 15});
dog.al()
dog.al = function(){
    alert(this.name + ' lives ' + (this.age+10) + ' years');
}

dog.al()
Animal.prototype.al()

// ::: dog lives 15 years
// ::: dog lives 25 years
// ::: noname lives 0 years


А лучше без сахара:



Animal={
 name: "noname",
 age: 0,
 create: function(name, age){
  var o=Object.create(this)
  o.name=name
  o.age=age
  return o
 },
 al: function(){alert(this.name+" lives "+this.age+" years." )}
}

dog=Animal.create("dog", 15)
dog.al()
dog.al=function(){alert(this.name+" lives "+(this.age+10)+" years." )}
dog.al()
Animal.al()


Цитата:

Сообщение от jesteross
но тут я не пойму, что именно будет в этом замыкании

Ничего там не будет. У тебя нет там никакого лексического контекста. Да и самого замыкания там скорей всего не будет. Чтобы точно утверждать, надо знать реализацию, конечно. Но, я думаю, замыкание вообще не будет создано. Короче, можешь считать, что его там просто нет.

theKingOfJava 09.04.2015 06:07

Цитата:

Сообщение от jesteross
на что влияет?

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


Часовой пояс GMT +3, время: 12:18.