Javascript 为什么这指的是基于括号放置位置的窗口或对象?和返回未定义
我正在开发灵活的javascript小部件。在一些测试过程中,我注意到Javascript 为什么这指的是基于括号放置位置的窗口或对象?和返回未定义,javascript,Javascript,我正在开发灵活的javascript小部件。在一些测试过程中,我注意到this的上下文根据调用函数的括号是放在对象内部还是放在其调用的全局上下文中而变化。为什么括号很重要?为什么对象中的括号指的是窗口,而当置于全局上下文中时,括号指的是对象。看起来情况正好相反 在这两种情况下都返回未定义的。有没有一种方法可以在不返回任何内容的情况下执行函数 我觉得我错过了一些关于的重要内容,我不想错过 //this refers to window var dataSource = { read: r
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()。它在没有任何上下文的情况下被调用,因此它的this
是窗口
(根据规范,其中窗口
是浏览器的全局对象)
第二个示例引用了read()
,然后在块的末尾执行。因为它是作为dataSource
的属性执行的,所以它的this
将变成this。但是,如果您首先将该引用分配给其他地方,然后通过该引用调用它,您将再次丢失该上下文
有关此的细粒度控制,请查看bind()
、call()
和apply()
在这两种情况下都返回未定义的。有没有一种方法可以在不返回任何内容的情况下执行函数
函数总是有一个返回值(未定义的
,如果没有显式设置),但您可以随意忽略它。您的代码正在做两件不同的事情
第一个示例是在执行对象定义时执行read()。它在没有任何上下文的情况下被调用,因此它的this
是窗口
(根据规范,其中窗口
是浏览器的全局对象)
第二个示例引用了read()
,然后在块的末尾执行。因为它是作为dataSource
的属性执行的,所以它的this
将变成this。但是,如果您首先将该引用分配给其他地方,然后通过该引用调用它,您将再次丢失该上下文
有关此的细粒度控制,请查看bind()
、call()
和apply()
在这两种情况下都返回未定义的。有没有一种方法可以在不返回任何内容的情况下执行函数
函数总是有一个返回值(未定义
,如果未显式设置),但您可以随意忽略它。此
的范围在javascript中可能是一个棘手的话题。也就是说,如果需要的话,我可以扩展我关于此
范围的一般规则的答案
但是为了回答您的特定问题,每当您在对象文本中引用this
,它默认情况下都引用对象文本本身
编辑:只要函数作为对象文本的属性调用。
其中,几乎在我能想到的任何其他情况下,this
将引用窗口对象,除非在使用apply()
或call()
调用所述函数时指定,否则this
的范围在javascript中可能是一个棘手的话题。也就是说,如果需要的话,我可以扩展我关于此
范围的一般规则的答案
但是为了回答您的特定问题,每当您在对象文本中引用this
,它默认情况下都引用对象文本本身
编辑:只要函数作为对象文本的属性调用。
其中,几乎在我可以想到的任何其他情况下,此
将引用窗口对象,除非在使用apply()
或call()调用所述函数时指定
当此
在对象之外使用时,它指的是浏览器环境中为窗口
的全局对象。否则,它指调用中最后一个点之前的最后一个单词
例如:
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
请注意,不添加参数并不是调用函数。因此,当您这样做时,应该很明显:
var bar = { foofoo : foo() }
您所做的是将函数foo
的结果传递到bar.foooo
。调用函数时,其调用路径中没有任何“点”。因此,它不属于任何对象,因此this==window
的规则适用
另一方面,如果您这样做:
var bar = { foo : foo }
您要做的是将函数foo
分配给bar.foo
。当您稍后将其称为:
bar.foo()
该调用包含一个“点”,因此,关于最后一个点之前的最后一个对象的规则适用
有关此
在javascript中如何工作的详细说明,请参见我之前对相关问题的回答:当此
在对象之外使用时,它指的是浏览器e中的全局对象