underscorejs - extendOwn 与 extend 之间有什么区别?

underscorejs - what is the difference between extendOwn vs extend?

正在经历 underscorejs's list of methods, I couldn't help but notice a method which I don't remember being there before: extendOwn

documentation for this method 表示如下:

extendOwn _.extendOwn(destination, *sources) Alias: assign

Like extend, but only copies own properties over to the destination object.

我明白了.extend() is used and what it does... but for the life of me I cannot understand how it differs from .extendOwn()

我尝试使用 .extend() and then .extendOwn() 扩展一些对象,只是为了看看是否可能会发生一些明显的事情 - 但它们似乎都产生相同的结果。

var a = {
    foo: false
};

var b = {
    bar: true
};

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

如果能深入了解这个谜团,我们将不胜感激!

所以对于任何想知道的人来说,找到答案的好地方是:https://github.com/jashkenas/underscore/search?q=extendOwn&type=Issues&utf8=%E2%9C%93

更新

对于任何感兴趣的人,答案是 extendOwnObject.assign 的同义词,只是实现方式略有不同。 Underscorejs 只是添加了一个替代品。他们不是用 Underscorejs 的新实现覆盖 assign 并将其称为 _.assign,而是将其称为 _.extendOwn_.assign_.extendOwn 的别名)。

这种命名约定的原因是可以理解的,但恕我直言有点混乱。你看,Object.assign 是 ES6 对 method/logic 的正式名称,我们称之为 "extend"(由 jQuery 和 Underscore 等工具调用)。

The decision by the Underscore team 是他们决定调用 primary/parent 方法 extendOwn 来遵守他们自己的内部标准。将主要方法命名为 _.assign 将(对 Underscore 的团队而言)与他们的直觉相反,它混淆了 "extend" 的作用。通过调用它 extendOwn,他们说这个方法与 "extend" 做同样的事情,但基于 ES6 对这个功能的实现,称为 "assign".

本质上-他们在这里遇到的是一个悖论,他们需要做出决定。他们要么坚持我们所知的约定 "extend",要么允许 "assign" - 这只会与原始名称冲突(这也可能会开始让人们质疑为什么他们仍然会调用另一个方法 "extend" 而不是 assignSomethinghere

长话短说 - extendOwn 是 ES6 Object.assign 的 Underscore 版本。他们只是将其命名为 extendOwn 以使其与命名约定保持一致,即命名为 extend.

"Own properties"是JS中的一个专业术语。对象自身的属性是它没有继承的属性。

这是一个简短的片段,揭示了 extendextendOwn 的不同行为:

// 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