Javascript 使接收器的函数默认为全局对象的基本原理是什么?

Javascript 使接收器的函数默认为全局对象的基本原理是什么?,javascript,Javascript,在早期版本的JavaScript中,将接收器(又称上下文)默认设置为全局对象的基本原理是什么 function a() { console.log(this); // window } 布伦丹·艾奇: 这样顶级功能(第一个版本中唯一的一种)就可以发挥作用 作为窗口或帧(稍后称为iframe)方法。仍然使用 JS行话nit:“接收者”是语言中的标准OO术语 这影响了JS,而不是超负荷的“上下文” 向Brendan Eich提出的问题: 所以ES1没有方法?(参见您对顶级fns的评论) 布伦丹

在早期版本的JavaScript中,将
接收器
(又称
上下文
)默认设置为全局对象的基本原理是什么

function a() {
  console.log(this); // window
}
布伦丹·艾奇:


这样顶级功能(第一个版本中唯一的一种)就可以发挥作用 作为窗口或帧(稍后称为iframe)方法。仍然使用

JS行话nit:“接收者”是语言中的标准OO术语 这影响了JS,而不是超负荷的“上下文”

向Brendan Eich提出的问题:

所以ES1没有方法?(参见您对顶级fns的评论)

布伦丹·艾奇:

不,1995年的JS1(当时没有“ES”)通过 函数值属性,但所有函数都是顶级的。 ES1标准化

1999年ES3增加了函数表达式和嵌套函数 (关闭),在那10天里我没有时间实施

要返回到窗口w中的原始q:m()函数{}生成w.m() 可从其他可访问的窗口/帧调用
this
==w


因此,顶级函数可以作为裸函数(即,不作为方法)从与同一“顶级”窗口关联的其他窗口和框架进行简单调用

例如,如果一个页面包含两个框架,每个框架定义自己的函数
foo
,该函数记录全局对象的属性。像这样:

index.html:

<html>
  <title>index.html</title>
  <frameset cols="30%,70%">
    <frame name="Frame1" src="frame1.html">
    <frame name="Frame2" src="frame2.html">
  </frameset>
var foo1, foo2;
foo1 = window.top.Frame1.foo;
foo2 = window.top.Frame2.foo;

foo1(); // "window object one!"
foo2(); // "window object two!"
因此,我们可以看到接收方默认为函数上下文的全局对象

另一种实现方式是让裸函数的接收方默认为未定义,但在JavaScript的早期,这被认为是“不太方便的”。请记住,JS最初是在考虑非专业开发人员的情况下开发的

当我们问这个问题时,问题变得更加有趣,为什么这种行为会扩展到嵌套函数和函数表达式(在ES3中标准化,但事先实现)?根据阅读Brendan Eich的回答,我猜测在开发嵌套函数和函数表达式时,这根本不是一个公认的问题,因此使用了基于顶级函数的现有行为


这个问题只有在ES5中才被正式承认,因为“使用严格的”

你必须询问他的原因,-)AndyE:Owwait,我很傻,不管我刚才说什么:我想如果
这个
始终是一个有效的对象,它会简化事情,但如果有人能给出一个来源丰富的答案,我会感到惊讶。有人问布伦丹:这个问题不是基于观点的。它正在寻找一个真实的答案。诚然,似乎唯一知道答案的人是该语言的原创者,但这并不能否定这个问题。因为我不习惯JS的最初几天,所以我不能完全理解这一点。所以我把它发布为社区维基,请随意改进。我想,一种解释是,像
window这样的方法。addEventListener
是一种“window方法”。他们希望人们能够编写不依赖于
窗口
全局对象的新窗口方法(
window.addSuperTurboEventListenerTournameEdition
)。因此,当添加新的顶级函数(他们最初考虑的唯一一种)时,它被视为“窗口方法”。我想这是有意义的,因为JavaScript作为一种语言几乎没有意义。因此,如果我正确理解这一点,那么将
接收器默认为全局对象(即
窗口
)的选择源于试图使用多个窗口(以及以后的iFrame)更方便。我想布伦丹逃过一劫,完全详细地回答了这个问题!真正的问题不是顶级函数,因为对它们来说,将其与全局执行上下文关联是有意义的,但我想更多地解释为什么嵌套函数上下文应该与全局上下文关联。这才是真正的问题。
<html>
  <title>frame2.html</title>
  <script>
    function foo() {
      console.log('frame2::foo: ', this.id);
    }
    this.id = 'window object two!';
  </script>
var foo1, foo2;
foo1 = window.top.Frame1.foo;
foo2 = window.top.Frame2.foo;

foo1(); // "window object one!"
foo2(); // "window object two!"