为什么根据括号的位置来引用窗口或对象?并返回undefined
Why does this refer to window or object based on where parenthesis are placed? And return undefined
我正在开发灵活的javascript小部件。在一些测试过程中,我注意到this
的上下文会根据用于调用函数的括号是放在对象内部还是放在其调用的全局上下文中而发生变化。为什么括号很重要?为什么对象内部的括号指的是窗口,而放在全局上下文中时指的是对象。看起来情况正好相反。
此外,在这两个实例中都返回undefined
。有没有一种方法可以在不返回任何内容的情况下执行函数?
我觉得我错过了this
的一些重要内容,不想错过。
//this refers to window
var dataSource = {
read: read()
};
function read(){
console.log(this);
}
dataSource.read;
//this refers to dataSource object
var dataSource = {
read: read
};
function read(){
console.log(this);
}
dataSource.read();
您的代码正在做两件不同的事情。
第一个例子是在执行对象定义时执行read()
(read()
是可用的,因为它是一个函数声明,并且是挂起的,尽管这与您遇到的问题无关)。它在没有任何上下文的情况下被调用,因此它的this
是window
(根据规范,其中window
是浏览器的全局对象)。
第二个例子引用了read()
,然后在块的末尾执行。因为它是作为dataSource
的一个属性执行的,所以它的this
将变成那个。但是,如果您首先将该引用分配给其他地方,然后通过该引用调用它,则会再次丢失this
上下文。
对于this
的细粒度控制,请查看bind()
、call()
和apply()
。
此外,在这两种情况下都返回
undefined
。有没有一种方法可以在不返回任何内容的情况下执行函数?
函数总是有一个返回值(如果没有显式设置,则为undefined
),但您可以忽略它。
在javascript中,this
的作用域可能是一个棘手的主题。也就是说,如果需要的话,我可以扩展我对this
范围的一般规则的回答。
但为了回答您的特定问题,每当您在对象文字中引用this
时,默认情况下,它指的是对象文字本身。
编辑:只要函数是作为对象文字的属性调用的
其中,几乎在我能想到的任何其他情况下,除非在使用apply()
或call()
调用所述函数时指定,否则this
将引用窗口对象。
当this
在对象之外使用时,它指的是全局对象,在浏览器环境中为window
。否则,它指的是调用中最后一个点之前的最后一个单词。
例如:
function foo () {return this};
var bin = {bar:{foo:foo},foo:foo};
foo(); // returns window
bin.foo(); // returns bin
bin.bar.foo(); // returns bar
// ^
// |
// '------ last bareword before the last dot in the invocation
现在,关于为什么括号的位置很重要。我想你现在应该能猜到了:
当我们在单词(变量/名称/引用)中添加括号时,我们要做的是进行函数调用:
foo(); // call foo
如果我们不加括号,我们所做的就是引用对象:
foo; // this contains the function foo
请注意,不添加parens并不是在调用函数。因此,当你这样做时,应该很明显:
var bar = { foofoo : foo() }
您正在做的是将函数foo
的结果传递给bar.foofoo
。函数的调用路径中没有任何"点"。因此它不属于任何对象,因此适用this == window
规则。
另一方面,如果你这样做:
var bar = { foo : foo }
您要做的是将函数foo
分配给bar.foo
。当您稍后将其称为:
bar.foo()
调用包含一个"点",因此应用关于最后一个点之前的最后一个对象的规则。
关于this
如何在javascript中工作的详细解释,请参阅我之前对相关问题的回答:;这个";Javascript中的关键字在对象文字中起作用?
- 调整窗口大小时,可拖动的对象会出现在容器外部
- 如何在选项卡上定义属性'的主窗口对象
- Javascript对象类在单击时打开窗口进行颜色选择,并在更改时替换对象背景颜色
- 可以从Chrome扩展修改窗口对象吗
- 在Backbone.js中为窗口对象指定变量
- 从html锚元素传递窗口对象
- 如何在ReactJS中使用窗口对象
- 在angularJS中使用模态窗口时,在控制器之间共享对象数组
- HackReactor,编码窗口现在可以访问一个名为“”的对象;招生;使用名为“;showApp”;.调用此方法时不带任
- 在加载时调用时,窗口对象的某些变量丢失
- 是否可以模拟 qUnit 测试的窗口位置对象
- 清除 Javascript 中窗口对象中的自定义变量
- 为什么当我尝试将函数绑定到自身时,“this”对象仍然引用窗口
- 窗口对象属性返回一个dom节点
- 使用窗口对象练习我的对象文字函数
- 如何从Chrome扩展访问所有窗口对象
- “this”返回的是[对象窗口],而不是元素
- 将变量打印到控制台时出现意外字符串:[对象窗口]
- 当我提醒“;这个“;鼠标悬停在<td>[对象窗口]弹出-那是什么
- javascript[对象窗口]在一个concat字符串