有人可以帮助我理解为什么下面的代码打印 Inside splitName function = [object Window]
为什么“这”是指Window对象?
let emp = {
fName: '',
lName: '',
setName: function(name) {
console.log("Inside setName function = " + this)
let splitName = function(n) {
console.log("Inside splitName function = " + this)
let nameArr = n.split(' ');
this.fName = nameArr[0];
this.lName = nameArr[1];
}
splitName(name);
}
}
emp.setName('ABC DEF');
console.log(window.fName);
答案 0 :(得分:0)
可以使用Function#call()
来传递对象上下文
let emp = {
fName: '',
lName: '',
setName: function(name) {
console.log("Inside setName function = " + this)
let splitName = function(n) {
console.log("Inside splitName function = " + this)
let nameArr = n.split(' ');
this.fName = nameArr[0];
this.lName = nameArr[1];
}
splitName.call(this, name);
}
}
emp.setName('ABC DEF');
console.log(emp.fName);
答案 1 :(得分:0)
我建议将您的方法splitName
更改为对象上的方法。这样,它将知道this
将引用您的对象emp
。否则,因为它是一个独立的函数,这意味着this
在默认情况下将引用window
,因为没有调用上下文。
let emp = {
fName: '',
lName: '',
splitName: function(n) {
console.log("Inside splitName function = " + this)
let nameArr = n.split(' ');
this.fName = nameArr[0];
this.lName = nameArr[1];
},
setName: function(name) {
console.log("Inside setName function = " + this)
this.splitName(name);
}
}
emp.setName('ABC DEF');
console.log(window.fName);
console.log(emp.fName);
答案 2 :(得分:0)
将您的splitName函数声明更新为Arrow函数,然后它将其作为父级的作用域,并且将按预期工作。
您可以了解how "this" works here。
并了解Arrow functions here.
let emp = {
fName: '',
lName: '',
setName: function(name) {
console.log("Inside setName function = " + this)
let splitName = (n) => {
console.log("Inside splitName function = " + this)
let nameArr = n.split(' ');
this.fName = nameArr[0];
this.lName = nameArr[1];
}
splitName(name);
}
}
emp.setName('ABC DEF');
console.log(emp.fName + ' ' + emp.lName );
console.log(window.fName);
答案 3 :(得分:0)
由于上下文和词法作用域Lexical Scope以及javascript中的执行上下文。在javascript中,每个函数(非箭头)都具有执行上下文,而ES6 箭头函数没有自己的执行上下文。
对于构造函数,当我们使用新的javascript引擎初始化构造函数时,您会为其创建执行上下文,并将其分配给它。但是对于非构造函数,如果未使用function.Call或function调用它们,则应用即未设置,则由于词法作用域,它们将窗口范围视为最外部范围。
在浏览器控制台中尝试setContentOffset:animated:
,这将打印Window(因为它是DOM的父对象或最外部作用域)。
答案 4 :(得分:0)
您可以使用Apply函数将内部函数的内容绑定到封闭的对象。发生这种情况的原因是,在这种类型的闭包中,此是指窗口范围(全局范围)。
let emp = {
fName: '',
lName: '',
setName: function(name) {
console.log("Inside setName function = " + this)
let splitName = function(n) {
console.log("Inside splitName function = " + this)
let nameArr = n.split(' ');
this.fName = nameArr[0];
this.lName = nameArr[1];
}
splitName.apply(emp,[name]);
}
}
emp.setName('ABC DEF');
console.log(window.fName);