Подтвердить что ты не робот

Underscorejs - в чем разница между extendOwn и продлением?

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

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

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

Как и расширение, но только копирует собственные свойства в объект назначения.

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

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

var a = {
    foo: false
};

var b = {
    bar: true
};

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

Любое понимание этой тайны было бы очень благодарно!

4b9b3361

Ответ 1

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

Обновление

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

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

Решение команды Underscore заключалось в том, что они решили вызвать основной/родительский метод extendOwn для соблюдения своих собственных внутренних стандартов, Именование основного метода _.assign будет (интуитивно понятным для команды Underscore), он смущает то, что делает "расширение". Вызывая его extendOwn, они говорят, что этот метод делает то же самое, что и "расширяться", но основан на реализации ES6 этой функции, известной как "присваивать".

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

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

Ответ 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