谁能告诉我下面两个代码之间的区别:
var Person = {
Cars: [],
init: function(){
this.Cars = [];
}
};
和
var Person = {
Cars: [],
init: function(){
Person.Cars = [];
}
};
一个正在使用“ this”,另一个正在使用“ Person”。
谢谢
答案 0 :(得分:1)
在第二个代码中,init
将总是在Cars
上创建(或重新分配)Person
属性。另一方面,在第一个代码中,在其上创建Cars
属性的对象取决于调用上下文。例如,如果将init
函数放到另一个对象上然后调用它,则另一个对象将发生变异:
var Person = {
Cars: [],
init: function(){
this.Cars = [];
}
};
var myVar = {};
myVar.init = Person.init;
myVar.init();
console.log(myVar);
如果使用.call
,您可以做同样的事情:
var Person = {
Cars: [],
init: function(){
this.Cars = [];
}
};
var myVar = {};
Person.init.call(myVar);
console.log(myVar);
引用this
时,是指调用上下文,而不是静态变量/对象。
答案 1 :(得分:0)
这里发生了2种不同的事情,因此在尝试进行比较时意识到差异很重要。
var Container = {
Cars: [],
init: function() {
this.Cars = [];
}
};
var Shipment = {
Cars: [],
init: function() {
Shipment.Cars = [];
}
};
让我们从第二个开始(命名为Shipment
,以便我们更好地区分它们)。
我们拥有的是一个带有单个方法的对象常量,该方法在被调用时会将属性Cars
的值分配给数组。
JS将首先尝试查找什么是Shipment
及其定义位置。当前词汇范围/上下文中未定义它,因此它将向上一级。并且向上一级直到找到它为止。这就是为什么您也可以通过相同的方法从此处访问Container
类的原因。
在这种情况下,由于它是在全局范围内执行init
函数之前 定义的,因此可以找到它。因此,我们找到Shipment
,然后将数组分配给它。因此,我们所做的实际上是在当前范围之外寻找对象文字,并一直寻找直到找到它为止。如果我们不能JS显然会抛出错误。当您进行use strict和default binding
时,还有很多其他功能,但这可能有点不合时宜。
在第一种情况下,我们要求JS在当前词法上下文中为我们提供方法的所有者。这就是this
的含义。猜猜...所有者是Container
,对我们来说幸运的是,我们可以按照计划随Cars属性的分配一起移动。
现在请记住,根据执行情况this
可能具有very different meaning
,对于ES6箭头功能,它将始终为enclosing lexical context。然后,借助ECMAScript 5和诸如call和bind之类的功能,您可以基本实现所需的功能(尽管近来在实践中对此并不满意)。但是在这个特定的例子中,我认为应该涵盖大部分内容。
希望这会有所帮助。