I know that adding a method to the prototype this way is not the best, but I'm just testing.
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));
I am getting:
[NaN, Infinity, Infinity]. I think the problem is "this.length".
You're right, the problem is this.length
. The trouble is that it's not in the function ! It's in a lambda, whose scope is not that of the array by which it's later invoked. As such, this
is not the array, and this.length
is a solid 0 (0/0 being NaN, 2/0 being infinity and 3/0 also being infinity).
You can either hardcode the real value 3
, or move your logic into the function itself. Or you could have the lambda (actually an "arrow function" in JavaScript) take another parameter: that of the denominator.
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));
this
inside an arrow function references the same this
in its containing block. Here, the containing block is the top level, where this
refers to window
, and window.length
is 0
.
console.log(this === window); console.log(window.length);
So, your code is equivalent to:
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
is undefined
, while most any other number / 0
is Infinity
(or -Infinity
).
If you want to emulate Array.prototype.map
's behavior with this
, the second argument passed to maap
should be the this
value the callback is invoked with:
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 ));
I think the problem is on the arrow function (the param transform
), Yes, this.length
is the directly related questions, go deeper, it's a problem about arrow function ,
An arrow function does not have its own
this
. Thethis
value of the enclosing lexical scope is used;
Simply put, where the arrow function defined where the this
point.
So, for your code, The parameters you passed in is n => n / this.length
, and it is defined in function console.log
in the environment of window
. So the real problem is:
transf = (n) => {
console.log(this); // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
return n / this.length
}
console.log([0, 2, 3].maap(transf));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.