var user = {
firstName: 'Вася',
sayHi: function(who) {
console.log(`firstname - ${this.firstName}: Привет, ${who}`);
}
}
setTimeout( function() {user.sayHi('asd')}, 2000 );
我得到 user.sayHi 不是函数错误,因为未在setTimeout调用的上下文中定义 user 。 afaik setTimeout上下文是窗口,并且通过 var 定义对象会将对象放入 window对象,然后为什么未定义对象( 1 )?< / p>
2 。改变var让它可以工作!为什么?
3 。键入
var x = user
并将 user.sayHi 更改为 x.sayHi 也可以!我不明白为什么。由于var x和var user对我来说是相同的定义。 请解释
答案 0 :(得分:-1)
我只是在这里猜测,但认为您是在用户循环中使用超时,例如:
var users = [1, 2];
for (var i = 0; i < users.length; i++) {
setTimeout(() =>
console.log(
'why 2?',
i,
'users[2] is undefined',
users[i],
),
);
}
如果您使用let
,则变量i是块作用域的,则每个循环都具有自己的i:
var users = [1, 2];
for (let i = 0; i < users.length; i++) {
setTimeout(() =>
console.log(
'let works:',
i,
users[i],
),
);
}
如前所述;之所以起作用,是因为每个操作都有自己的i变量,但使用var时只有window.i,而setTimeout函数执行window.i时的值为2。接下来将通过一个额外的console.log进行演示。
var users = [1, 2];
for (var i = 0; i < users.length; i++) {
setTimeout(() =>
console.log(
'now you know why 2!',
i,
'users[2] is undefined',
users[i],
),
);
}
console.log('after the loop before the timeout, and i is:',i);
您的var代码可能有效,因为您正在创建将包含最后一个用户的用户变量:
var users = [1, 2];
for (var i = 0; i < users.length; i++) {
var user = users[i]
setTimeout(() =>
console.log(
'i still is 2',
i,
'user is 2 both times as there is only one window.user',
user,
),
);
}
console.log('after the loop, user is:',user);
因此,您可以使用let作为解决方案,但我更喜欢使用forEach:
var users = [1, 2];
users.forEach((user) =>
setTimeout(() =>
console.log(
'no more temporary i counter variable, user is:',
user,
),
),
);
console.log('after foreach');
如果我完全错了,那么对此感到抱歉,因为您正在描述一个常见的循环问题,但是发布的代码却不会导致您描述的任何行为,因此不得不猜测。