2012-03-11 2 views
13

jQuery имеет очень аккуратный метод extend, который объединяет 2 объекта в один.Зачем передавать пустой объект в метод расширения jQuery?

На jQuery Plugins authoring page они показывают пример следующим образом:

var settings = $.extend({ 
    'location'   : 'top', 
    'background-color' : 'blue' 
}, options); 

Однако, я видел много плагинов передать пустой объект в качестве первого параметра, например, так:

var settings = $.extend({}, { 
    'location'   : 'top', 
    'background-color' : 'blue' 
}, options); 

Что касается как я могу судить, эти двое делают то же самое. Единственное различие было бы, если бы defaults хранились в своей собственной переменной:

var defaults = { 
    'location'   : 'top', 
    'background-color' : 'blue' 
}, 
settings = $.extend({}, defaults, options); 

Таким образом, вы всегда можете получить доступ к по умолчанию без них быть переопределены options.


Вот вопрос: Почему так много плагинов авторы решили передать пустой объект extend, даже если они не хранят значения по умолчанию в переменной?

Я что-то упустил?

+1

Кажется бессмысленным для меня. Это делает населенный, копируя его в пустую и отбрасывая. Ваш третий пример показывает действительную причину. Я предполагаю, что люди это делают, потому что они не думают о том, что они делают. –

+0

@amnotiam Это именно то, что я думаю, но я видел * так много * плагинов. Ясно, что я что-то пропустил ... –

+0

Нет, я думаю, что проблема в том, что вы * что-то получаете. –

ответ

8

Возможные причины (для второго примера) ...

  • Наследуется невежество ...(видел, что это сделано таким образом, и скопировал практику)

  • взрывобезопасности невежество ... (видел это сделано должным образом, как в последнем блоке кода, но заменил кэшированные объект с объектом на лету и не знал, что пустой объект должен быть удален)

  • Глобальное потепление.

  • Недостаток внимания к деталям ... (аналогично точке 2, знает, что это не нужно, но никогда не нашел время, чтобы изучить код)

  • Глобальное охлаждение.

  • Чрезмерно оборонительное кодирование ... (боится, что по умолчанию может быть когда-нибудь переработано многократно используемым объектом, и боятся, что пустой объект не будет вставлен в то время)

  • разработчиков JQuery всегда делайте то, что им говорят голоса ;-)

В целом, вы правы. Средний объект создается, копируется в пустой объект, затем отбрасывается. Это ненужная и расточительная практика.

9

Расширение - очень полезная функция для копирования объектов.

Для примера рассмотрим следующее:

foo = {'foo':'a'} 
f = foo 
f.foo = 'hello' 
console.log(f) 
    Object {foo="hello"} 
console.log(foo) 
    Object {foo="hello"} 

f = $.extend({},foo) 
f.foo = 'hello world' 
console.log(f) 
    Object {foo="hello world"} 
console.log(foo) 
    Object {foo="hello"} 

Так как вы можете видеть $ .extend фактически скопирован объект.

EDIT

Причина, почему первый параметр должен быть пустой объект из-за того, как extend работ. Вот как JQuery определяет extend:

jQuery.extend(target [, object1] [, objectN]) 
    target An object that will receive the new properties 
      if additional objects are passed in or that will 
      extend the jQuery namespace if it is the sole argument. 
    object1 An object containing additional properties to merge in. 
    objectN Additional objects containing properties to merge in. 

И кроме того, эта фраза важна:

Имейте в виду, что целевой объект (первый аргумент) будет изменен, и также будет возвращен из $ .extend().

Таким образом, передавая {} в качестве первого параметра, этот пустой объект расширяется, а затем возвращается.

Возврат к вашему примеру settings = $.extend({}, defaults, options);. Если вы измените его на settings = $.extend(defaults, options);, настройки будут одинаковыми, но здесь будут также изменены значения по умолчанию. Вот почему вам нужно, чтобы первый аргумент был {}.

+0

Спасибо за ваше обновление, но это именно то, что я описал в своем вопросе. Я понимаю преимущество использования пустого объекта в моем третьем примере. То, что я пытаюсь понять, - это разница между моими 1-м и 2-м примерами ... –

+0

Думаю, я не следовал вашему вопросу. Мне нравится ответ wiki сообщества на вопрос, почему люди любят писать пример №2. – miki725

+0

Я наконец понял, что вы правы, когда я случайно разрушил свой первый объект в '$ .extend {}', который я не ожидаю, что он будет изменен. – jasonslyvia

3

Другой способ положить, что Мики сказал:

var defaults = { 
    one: 'foo', 
    two: 'bar' 
}; 

var options = { 
    two: 'apples', 
    three: 'bananas' 
}; 

// The safe way to extend 
var settings = $.extend({}, defaults, options); 

console.log(settings); // {one: 'foo', two: 'apples', three: 'bananas'} 
console.log(defaults); // {one: 'foo', two: 'bar'} 
console.log(options); // {two: 'apples', three: 'bananas'} 
console.log(settings === defaults); // false 

// Careless way to extend 
var settings = $.extend(defaults, options); 

console.log(settings); // {one: 'foo', two: 'apples', three: 'bananas'} 
console.log(defaults); // {one: 'foo', two: 'apples', three: 'bananas'} 
console.log(options); // {two: 'apples', three: 'bananas'} 
console.log(settings === defaults); // true 
+0

Опять же, это именно то, что я изложил в своем вопросе. См. Мой третий кусок кода (и его предыдущий абзац). –

+0

Думаю, я не понимаю, что ты тогда задаешься вопросом. Вы спрашиваете: почему так много авторов плагина предпочитают пропускать пустой объект? Мой ответ, вероятно, почему. Хранение значений по умолчанию в переменной не помешает их перезаписывать. – ianstarz

+0

Мой вопрос: почему так много авторов плагина предпочитают пропускать пустой объект для расширения *, даже если они не сохраняют значения по умолчанию в переменной *? Я уточнил свой вопрос, чтобы уточнить это. –

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