2016-06-10 2 views
1

Я - новичок в JavaScript. Я сделал довольно много поиска в Google, но не смог найти ответ, который я ищу, скорее всего, потому что я использую неправильную терминологию.JavaScript и значения по умолчанию для прототипа

На днях я читал основной учебник о создании компонентов JavaScript: http://callmenick.com/post/javascript-objects-building-javascript-component-part-2

Часть урока включает в себя набор параметров по умолчанию, которые отнесены к цепочке прототипов типа А в:

SimpleAlert.prototype.options = { 
    wrapper : document.body, 
    type : "default", 
    message : "Default message." 
} 

Идея состоит в том, что тип SimpleAlert может быть создан с различными параметрами, если пользователь предоставляет их во время построения - в противном случае используются параметры по умолчанию.

SimpleAlert конструктор функции выглядит следующим образом:

function SimpleAlert(options) { 
this.options = extend({}, this.options); // Why? 
extend(this.options, options); 
// start the functionality... 
} 

и функция extend определяется как:

function extend(a, b) { 
for(var key in b) { 
    if(b.hasOwnProperty(key)) { 
    a[key] = b[key]; 
    } 
} 
return a; 
} 

Мое понимание этого кода:

Создание нового объекта SimpleAlert включает пользователя, проходящего в свой собственный объект options. Скажем, я перехожу в { test : "Testing" } для параметра options. Затем функция extend обращается к this.options (которая, как мне кажется, относится к экземпляру прототипа options, поскольку в области нет другой переменной options) и по существу копирует все из общего экземпляра в пустой объект {}, который затем присваивается совместно используемому this.options экземпляр.

Затем пользователь поставляется options (в моем случае { test : "Testing" } является extend ред ИНТ совместно экземпляра this.options (в основном копируя мой дополнительный test поле в общий экземпляр)

Но на самом деле, кажется, что общий экземпляр не затрагиваются в данном примере - значение SimpleAlert.prototype.options декларации остается неизменным, так что каждый новый экземпляр SimpleAlert имеет доступ к нему (что я хочу)

Однако в моих экспериментах, я считаю, что изменение this.options результатов в прототипе ценность bein g изменен ... Я уверен, что все, что я делаю неправильно, просто исправить, но я не вижу этого. Вот пример:

var Animal = function(ovr) { 
     if (arguments.length > 0) 
     { 
     this.options.mode = ovr; 
     } 

    }; 

    Animal.prototype.options = { mode: "Test" };/I want this to be default for all instances created 

    var test = new Animal("Override"); // set this test obj to use "Overide" 
    console.log(test.options.mode); // outputs Override as expected 
    var again = new Animal(); 
    console.log(again.options.mode); // also outputs Override (I want it to say "Test") 

Благодарим за помощь!

ответ

0

Как вы уже указали в своем коде, отсутствует операция копирования, поэтому вы изменяете общий объект на прототипе.

var Animal = function(ovr) { 
    if (arguments.length > 0) { 
     // Copy whatever is on this.options to a blank object, 
     // then assign this.options to be that newly copied object, so 
     // the prototype object is masked by the instance object. 
     this.options = Object.assign({}, this.options); 
     this.options.mode = ovr; 
    } 
}; 

Это может помочь понять, как экземпляр собственности «маски», прообраза:

var Foo = function() { 
    console.log('a', this.x); 
    this.x = 100; 
    console.log('b', this.x); 
    delete this.x; 
    console.log('c', this.x); 
}; 

Foo.prototype.x = 1; 

new Foo(); 
+0

Спасибо за ваш ответ. Я все еще ничего не понимаю. this.options является общим экземпляром на прототипе, не так ли? Таким образом Object.assign ({}, this.options} копирует общий экземпляр в пустой объект ... но затем этот объект (теперь заполненный) переназначается обратно на this.options ...который является общим экземпляром, не так ли? – Adam

+0

Нет, это не так. Проще говоря, когда вы запрашиваете «this.options», он сначала проверяет экземпляр свойства options. Если этого не существует, то он ищет цепочку прототипов. Таким образом, опция экземпляра «маскирует» прототип. Обновленный ответ. –

+0

О, хорошо, поэтому назначение 'this.x' в функции конструктора' Foo' неявно создает переменную, которая затеняет переменную прототипа? Любопытно, что я замечаю, что если я изменяю 'this.x = 100;' на 'var x = 100', он не кажется теневым? – Adam

Смежные вопросы