我创建了一个普通的JavaScript对象,如下所示:
let obj = {
name : "something",
print() {
console.log(this.name);
}
}
let res = obj.print()
console.log(res);
在这个例子中,obj
有一个名字和一个简单的方法。我从外面打电话给这个方法。之后,我将返回值记录到控制台,这是未定义的。
我不明白对象内幕后发生了什么。请向我解释此代码的创建和执行阶段。
在幕后,JavaScript解释器在内存中创建一个对象并通过obj
引用它。当你调用obj.print()
时,它引用同一个对象并调用定义的方法。
在该方法中,this
引用对象本身(obj
),并由JS解释器设置为隐式引用。
最后,你忘了从print()
返回值。所以,没有任何东西被分配给res
。请参阅以下示例,因为当从函数返回值时,它会正确打印res
的值。
let obj = {
name: "something",
print() {
console.log(this.name);
return this.name;
}
}
let res = obj.print()
console.log(res);
我将写一篇关于你要求的“幕后”的文章。不幸的是,这可能会让你感到困惑,而不是让事情更清晰,因为JavaScript本身就是一种“不同”的语言。
在JavaScript中,函数是一个对象。有时甚至称为一流的对象。它拥有对象具有的所有内容(属性和方法),并且还可以进一步调用。不相信我?你自己看:
function abracadabra()
{
return "this is magic";
}
console.log(abracadabra.name);
console.log(abracadabra.call());
现在,方法只是对象的属性所引用的另一个函数。我们举个例子:
let obj = {
name : "something",
print() {
console.log(this.name);
}
}
这里obj
被定义为具有两个属性的对象。值类型和函数。当您调用obj.print()
函数时,会发生以下情况:
this
设置为调用该方法的对象。您可以使用this
访问同一对象的其他属性。什么是this
?如上所述,所谓的函数上下文可以根据函数的调用方式引用四个不同的对象。
abracadabra()
=> this
指的是全局上下文,默认情况下它总是指向它。全局上下文取决于执行JavaScript的环境。记住,JavaScript不仅可以在浏览器中运行。它还可以用作服务器端脚本语言。在浏览器中,全局上下文是当前的浏览器窗口。不相信我?你自己看:
// We are not in any method, still "this" is available:
console.log(this.toString());
obj.print()
=> this
指的是调用该方法的对象。我在上面描述了这个。new abracadabra()
=>创建一个新的空对象,this
指的是它。现在该函数应该使用属性扩展空对象。apply
或call
方法调用=> this
指的是您传递的任何内容作为这些方法的第一个参数。总而言之:真正理解这些东西如何在JavaScript中运行会变得棘手。这是因为语言中基本上只有对象和函数。方法看起来像方法,但实际上只是函数。
为了获得非常好的深度理解,我可以推荐这本书Secrets of the JavaScript Ninja。