我知道用这种方法向原型添加方法并不是最好的方法,但我只是在测试。
Array.prototype.maap = function (transform) {
let mapped = [];
for (let element of this) {
mapped.push(transform(element));
}
return mapped;
}
console.log([0, 2, 3].maap(n => n / this.length));
我得到:
[NaN,无穷大,无穷大]。我认为问题是“ this.length”。
答案 0 :(得分:3)
是的,问题是this.length
。麻烦的是它不在函数中!它在lambda中,其作用域不是后来被其调用的数组的作用域。因此,this
不是数组,this.length
是实数0(0/0为NaN,2/0为无穷大,而3/0也为无穷大)。
您可以对实际值3
进行硬编码,也可以将逻辑移入函数本身。或者,您可以让lambda(实际上是JavaScript中的“箭头函数”)采用另一个参数:分母的参数。
Array.prototype.maap = function (transform) {
let mapped = [];
for (let element of this) {
mapped.push(transform(element, this.length));
}
return mapped;
}
console.log([0, 2, 3].maap((n, m) => n / m));
答案 1 :(得分:1)
this
在其包含块中引用相同的this
。这里,包含块是顶层,其中this
指window
,而window.length
是0
。
console.log(this === window);
console.log(window.length);
因此,您的代码等效于:
Array.prototype.maap = function(transform) {
let mapped = [];
for (let element of this) {
mapped.push(transform(element));
}
return mapped;
}
console.log(this.length);
console.log([0, 2, 3].maap(n => n / 0));
0 / 0
是undefined
,而其他大多数数字/ 0
是Infinity
(或-Infinity
)。
如果您想用Array.prototype.map
模拟this
的行为,则传递给maap
的第二个参数应该是通过以下方式调用回调的this
值:>
Array.prototype.maap = function(transform, thisVal) {
let mapped = [];
for (let element of this) {
mapped.push(transform.call(thisVal, element));
}
return mapped;
}
const arr = [0, 2, 3];
console.log(arr.maap(
function(n){ return n / this.length; },
arr
));
答案 2 :(得分:1)
我认为问题出在箭头函数(参数transform
)上,是的,this.length
是直接相关的问题,更深入地讲,这是关于arrow function的问题,>
箭头功能没有自己的
this
。使用了封闭词法范围的this
值;
简单地放置,箭头功能定义this
点的位置。
因此,对于您的代码,您传入的参数为n => n / this.length
,并且在console.log
环境中的函数window
中进行了定义。所以真正的问题是:
transf = (n) => {
console.log(this); // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
return n / this.length
}
console.log([0, 2, 3].maap(transf));