我正在阅读《JavaScript Ninja 的 secret ,第二版》一书,它有以下代码:
function forEach(list,callback) {
for (var n = 0; n < list.length; n++) {
callback.call(list[n],n);
}
}
var weapons = ['shuriken','katana','nunchucks'];
forEach(weapons, function(index){
assert(this == weapons[index],
"Got the expected value of " + weapons[index]);
});
按照书上的说法似乎没问题。当“assert”发生时,“this”作为字符串返回。
但是当我自己运行代码时,“this”以字符数组的形式返回。
0:“一个”
1:“x”
2:“e”
长度:3
这是我的代码副本,稍加修改this.toString()
,它的工作原理与书中一样(我希望...)
function forEach(list, callback) {
for (let n = 0; n < list.length; n++) {
callback.call(list[n], n);
}
}
let weapons = [
'axe',
'sword',
'mace'
];
forEach(weapons, function (index) {
console.assert(this.toString() === weapons[index], `Got the expected value of ${weapons[index]}`)
})
我错过了什么或不明白什么?为什么相同的代码会给出不同的结果?
最佳答案
这是一段非常有趣的代码,我会留意那本书。首先,assert 方法是如何实现的?我做了一个小代码块,假设 assert 方法是如何实现的。
forEach
函数中的重要代码是 callback.call
方法。如果你看documentation :
function.call(thisArg, arg1, arg2, ...) thisArg Optional. The value of this provided for the call to a function. Note that this may not be the actual value seen by the method: if the method is a function in non-strict mode, null and undefined will be replaced with the global object and primitive values will be converted to objects.
本质上,this
变成了 list
中的值,在本例中是每个单词。您还提到了
run the code myself 'this' returned as an array of characters
它是一个字符串,它是一个字符数组。在字符串中,您可以执行 nameOfStringVar[index]
操作,您将获得该字符的位置。
console.log("hello"[1]);
它不是一个数组,而是一个 String 实例。此外,您还强制与 ===
进行类型比较,如 documentation 所示。 .
triple equals (===) will do the same comparison (including the special handling for NaN, -0, and +0) but without type conversion, by simply always returning false if the types differ;
但是有人会想,如果 this
应该是 list[n] 那怎么不是 ===
相同的 列表[n]
?
我假设幕后 JS 正在根据传递的值创建一个新对象,这就是为什么 '===' 返回 false。我一边输入一边搜索此内容,如果我发现任何具体内容,我将编辑此答案。
我想到了以下内容,使用 mauke's piece of code我为每个创建的对象添加一个 id。然后您会看到 this
与 weapons[index]
具有不同的 id
。
var enchant = (function () {
var k = 'id';
var uniq = 0;
return function enchant(o) {
var t = uniq++;
o[k] = function () {
return this === o ? t : enchant(this, k);
};
return t;
};
}());
enchant(Object.prototype);
function forEach(list,callback) {
for (var n = 0; n < list.length; n++) {
callback.call(list[n],n);
//list[n] is the new this, essentially the word
}
}
function assert(expression, message){
if(expression)
console.log(message);
else
console.log("Not equal");
}
var weapons = ['shuriken','katana','nunchucks'];
forEach(weapons, function(index){
console.log("this id is --> " + this.id());
console.log("weapoins[index] id is --> " + weapons[index].id());
assert(this == weapons[index],
"Got the expected value of " + weapons[index]);
});
function forEach(list,callback) {
for (var n = 0; n < list.length; n++) {
callback.call(list[n],n);
//list[n] is the new this, essentially the word
}
}
function assert(expression, message){
if(expression)
console.log(message);
else
console.log("Not equal");
}
var weapons = ['shuriken','katana','nunchucks'];
forEach(weapons, function(index){
assert(this == weapons[index],
"Got the expected value of " + weapons[index]);
});
关于javascript - 'this' 返回数组而不是字符串。 JavaScript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54324768/