underscorejs - в чем разница между extendOwn и extend?

Просматривая список методов underscorejs, я не мог не заметить метод, которого не помню. до: extendOwn

В документации для этого метода говорится следующее:

extendOwn _.extendOwn(destination, *sources) Псевдоним: назначить

Подобно расширению, но только копирует собственные свойства в целевой объект.

Я понимаю, как используется .extend() и что он делает... но на всю жизнь я не могу понять, чем он отличается от .extendOwn().

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

var a = {
    foo: false
};

var b = {
    bar: true
};

// This will produce { foo: false, bar: true }; ..just like _.extend() would =\
_.extendOwn( a, b );

Любое понимание этой тайны будет высоко оценено!


person Jonathon Hibbard    schedule 12.03.2015    source источник
comment
У меня нет - это хорошая идея, спасибо   -  person Jonathon Hibbard    schedule 13.03.2015
comment
хех, так я только что прочитал источник. Забавно, что все сводится к использованию .keys и _.allKeys, что, в свою очередь, отличается от использования nativeKeys и следующего: for (var key in obj) if (.has(obj, ключ)) keys.push(ключ); где другого нет. не знаю - мне все еще кажется загадкой, зачем вообще нужен extendOwn.   -  person Jonathon Hibbard    schedule 13.03.2015


Ответы (2)


«Собственные свойства» — это технический термин в JS. Собственные свойства объекта — это те, которые он не унаследовал.

Вот короткий фрагмент, демонстрирующий различное поведение extend и extendOwn:

// lines have length
line = { length: 4 }

// planes have width and inherit length
plane = Object.create(line)
plane.width = 5
plane.length  // 4

// making a cube object, using extend
cube = _.extend({ height: 6 }, plane)
cube.length  // 4

// making a cube object, using extendOwn
notACube = _.extendOwn({ height: 6 }, plane)
notACube.length  // undefined

Как видите, extendOwn скопировал только те свойства, которые были определены непосредственно в источнике, тогда как extend также скопировал свойства, определенные в цепочке прототипов. Также обратите внимание на симметрию с _.has:

_.has(plane, 'width')   // true
_.has(plane, 'length')  // false
person johncip    schedule 04.03.2016
comment
Этот ответ полезен. Документация Underscore действительно дерьмово объясняет это. - person luxon; 14.12.2016

Так что для тех, кто интересуется, ответ можно найти здесь: https://github.com/jashkenas/underscore/search?q=extendOwn&type=Issues&utf8=%E2%9C%93

Обновить

Кому интересно, ответ таков: extendOwn является синонимом Object.assign с реализация немного отличается. Underscorejs просто добавляет к нему альтернативу. Вместо того, чтобы переопределить assign новой реализацией в Underscorejs и назвать его _.assign, они называют его _.extendOwn (где _.assign является псевдонимом _.extendOwn).

Причина такого соглашения об именах понятна, но немного сбивает с толку. Видите ли, Object.assign — это официальное название ES6 для метода/логики, которую мы знаем как «extend» (вызываемую такими инструментами, как jQuery и Underscore).

Команда Underscore приняла решение позвонить в основной /parent методом extendOwn придерживаться собственных внутренних стандартов. Назвать основной метод _.assign было бы (для команды Underscore) нелогичным для них, это сбивает с толку то, что делает «extend». Назвав его extendOwn, они говорят, что этот метод делает то же самое, что и «extend», но основан на реализации ES6 этой функции, известной как «assign».

По сути - то, что они имели здесь, было парадоксом, и им нужно было принять решение. Либо они придерживаются соглашения, которое мы знаем как «расширение», либо разрешают «назначать», что просто будет противоречить исходному имени (что также может вызвать у людей вопрос, почему они все еще называют другой метод «расширением», а не assignSomethinghere вместо этого).

Короче говоря, extendOwn — это версия Object.assign ES6 для Underscore. Они просто назвали его extendOwn, чтобы он соответствовал тому же соглашению об именах, которое называется extension.

person Jonathon Hibbard    schedule 12.03.2015