对象方法引用对象属性的两种方式之间的区别



有两种方法可以让对象方法引用对象属性:

let i = {a: 'apple', b: function(){return i.a}}
let j = {a: 'apple', b: function(){return this.a}}
console.log(i.b())  // apple
console.log(j.b())  // apple

引用对象属性的这两种方法的优缺点是什么??

它们的含义不同。第一个返回作用域中某个变量ia属性。该对象也被命名为i,这意味着它可以按预期工作。但这并不能保证。例如:

let i = {a: 'apple', b: function(){return i.a}}
let j = i
i = {a: "potato"}
console.log(j.b()) // apple or potato?

只要您期望函数查看范围,找到一个i并返回它的a道具,那么这就可以按预期工作。但这并不意味着,在这个函数中返回对象的a属性。

第二个是否意味着,只要它是用i.b()调用的,但this并不指定义函数的对象——它的值由函数调用的上下文决定。例如

let i = {a: 'apple', b: function(){return this.a}}
let j = {a: 'potato'}
j.b = i.b
console.log(j.b()) // apple or potato

一个并不比另一个更好,它们是不同的想法,可以发挥不同的功能。

实际上,这些函数并不是在做同样的事情。

让我们考虑第一个。

let i = {a: 'apple', b: function(){return i.a}}

您定义了一个函数function(){return i.a},它将从对象i返回一个值。无论何时何地调用它,它都将返回对象i的值。它完全独立于范围。不能将此函数作为原型的方法重用。因为i总是i。如果您没有使用箭头函数来保护您的呼叫上下文,那么它可能会很有用。

另一方面,其他功能是不同的。

let j = {a: 'apple', b: function(){return this.a}}

您正在使用this,因此它将根据其上下文访问属性a。


通过一个例子让一切变得更加清晰。假设我有一个属性为sound的绵羊和狗对象。

const dog = {
sound: 'woof-woof'
};
const sheep = {
sound: 'Meaeeeeee'
};

现在我正在定义一个函数makeSound

function makeSound {
alert(this.sound)
}

现在我想对这两种动物都使用makeSound。我所要做的就是通过给它一个上下文来调用这个函数。

makeSound.call(sheep) // -> Meaeeeeee
makeSound.call(dog) // -> woof-woof

this帮助我为不同类型的对象重用此函数。这就是原型遗传的来源。

最新更新