我有以下代码:
var gameController = {
scores: [20, 34, 55, 46, 77],
avgScore: 112,
players: [
{name: "Ruth", playerId: 100, age: 22},
{name: "Shawnee", playerId: 101, age: 21}
]
};
var appController = {
scores: [900, 845, 809, 950],
avgScore: null,
avg: function () {
var sumOfScores = this.scores.reduce(function (prev, cur, index, array) {
return prev + cur;
});
this.avgScore = sumOfScores / this.scores.length;
}
};
gameController.avgScore = appController.avg();
console.log(gameController.avgScore);
我尝试借用appController中定义的avg方法来为gameController进行计算。我理解在gameController.avgScore = appController.avg();
之后,avg方法中的这个关键字仍会指向appController,因为appController会调用avg方法,所以我希望gameController中的avgScore保持不变,但输出是未定义的,为什么?
答案 0 :(得分:2)
avg
不会返回任何内容,因此会隐式返回undefined
。你基本上在做gameController.avgScore = undefined;
。
如果您要将avg
方法应用于gameController
,可以使用.call
:
appController.avg.call(gameController);
最好将avg
作为独立函数接受数组作为输入(参数)并返回平均值。
答案 1 :(得分:1)
<强>更新强>
将函数赋值给对象时,在调用函数时将this关键字设置为对象。这仅适用于未绑定的函数引用。如果函数引用绑定到另一个对象,则必须使用Function.bind()
方法来确保将其设置为正确的对象。
<强>答案强>
而不是每次使用调用只是将函数分配给对象。调用该函数时,this
设置为对象
gameController.avg = appController.avg; // unbound function reference.
// now when you need to get the average for gameController
// just call its avg function
gameController.avg(); // this is automatically set to gameControler
最好还是在控制器外部创建功能,并在创建时分配它们。
// define the avg and refer it to the unbound function that you will share
var avg = function () {
var sumOfScores = this.scores.reduce(function (prev, cur, index, array) {
return prev + cur;
});
this.avgScore = sumOfScores / this.scores.length;
console.log(this.avgScore);
}
// create the objects as normal
var gameController = {
scores: [20, 34, 55, 46, 77],
avgScore: 112,
players: [
{name: "Ruth", playerId: 100, age: 22},
{name: "Shawnee", playerId: 101, age: 21}
],
avg:avg // avg is automatically bound to gameController when it is called
};
var appController = {
scores: [900, 845, 809, 950],
avgScore: null,
avg:avg // avg is automatically bound to appController when it is called
};
// or if you want to get really lazy.
var otherController = {
scores: [900, 900, 900, 900],
avgScore: null,
avg // avg is automatically bound to otherController when it is called
// and it is automatically named avg as well
};
appController.avg(); // 46.4
gameController.avg(); // 876
otherController.avg(); // 900
还有超过六种其他方法可以实现同样的目标。