Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么这指的是基于括号放置位置的窗口或对象?和返回未定义_Javascript - Fatal编程技术网

Javascript 为什么这指的是基于括号放置位置的窗口或对象?和返回未定义

Javascript 为什么这指的是基于括号放置位置的窗口或对象?和返回未定义,javascript,Javascript,我正在开发灵活的javascript小部件。在一些测试过程中,我注意到this的上下文根据调用函数的括号是放在对象内部还是放在其调用的全局上下文中而变化。为什么括号很重要?为什么对象中的括号指的是窗口,而当置于全局上下文中时,括号指的是对象。看起来情况正好相反 在这两种情况下都返回未定义的。有没有一种方法可以在不返回任何内容的情况下执行函数 我觉得我错过了一些关于的重要内容,我不想错过 //this refers to window var dataSource = { read: r

我正在开发灵活的javascript小部件。在一些测试过程中,我注意到
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中的全局对象