“又是关于闭包的疑问,比较高级的疑问”的结论,有ECMA的理论依据,也恳请cloudgamer来审阅一下

ykl4452 2009-11-13 11:26:55
又是关于闭包的疑问,比较高级的疑问的原文:又是关于闭包的疑问,比较高级的疑问

在“又是关于闭包的疑问,比较高级的疑问”一贴中,没有一个结论能够让自己信服 ,于是晚上又仔细翻了ECMA.
如果有错误,也希望各位能指点一下

首先精简一下代码,其实这段代码和“又是关于闭包的疑问,比较高级的疑问”中的代码原理是一样的,但相比之下更短,更能说明问题

var outwrap = function(){
var fn = function(){
//结果是[object Window]
alert(this);
};
fn();
};
var o = new outwrap();


在11.2.3 Function calls(ecma规范P44页)

看到这里,也许会问,难道fn的类型是一个Reference,而且GetBase()的结果是activation object?不错, 就是这样:
10.1.4 Scope Chain and Identifier Resolution(ecma规范P38页)

也就是说在执行fn()之前, 会沿着scope chain查找fn这个变量, 结果在当前作用域就找到了fn变量,所以GetBase()的结果只能是activation object……, 于是fn中的this先被置为null,再被置为window
...全文
170 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
dh20156 2009-11-14
  • 打赏
  • 举报
回复
貌似是 10.2.3
dh20156 2009-11-14
  • 打赏
  • 举报
回复
11.2.3 请再往下看到this段落 - -!
dh20156 2009-11-14
  • 打赏
  • 举报
回复
我在你上一个帖子里回复到:


[Quote=引用 http://topic.csdn.net/u/20091112/12/5dc4d07b-e918-490a-9397-ab81f9b49108.html #24楼 dh20156 的回复:]
关于this的最终回复,参见ECMA-262 10.2.3:


The caller provides the this value. If the this value provided by the caller is not an object (including the case where it is null), then the this value is the global object.


其他的参见Javascript Scope Chain相关资料。
[/Quote]

希望你看一下这部分,Cloudgamer也跟你提到过,不过貌似你却没去看这里。
xiaofan_sap 2009-11-14
  • 打赏
  • 举报
回复
阿q一下 还记得闭包中循环变量的问题吗 内层函数调用的循环变量都是其最终值 ,因为内层函数的作用是是在其定义是确定的,也就是外层函数执行的时候。所以是最终值。而this可以不以这样理解。抛砖引玉~~~
ykl4452 2009-11-14
  • 打赏
  • 举报
回复
“闭包中的this指向window”这个结论很简单,也很容易记忆,但是背后的原理却不是那么简单的,我贴这个帖子主要是确定一下"背后的原理"
ykl4452 2009-11-14
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 dh20156 的回复:]
貌似是 10.2.3
[/Quote]
版主大人,如果我有讲得不正确的地方,一定要指点一下啊
ykl4452 2009-11-14
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 xiaofan_sap 的回复:]
难道闭包时 this指向了作用域链的最顶端?
[/Quote]
恩,我的理解是这样, 但不确定自己有没有理解错,如果有错,欢迎指正
xiaofan_sap 2009-11-14
  • 打赏
  • 举报
回复
难道闭包时 this指向了作用域链的最顶端?
ykl4452 2009-11-14
  • 打赏
  • 举报
回复
明白了,我错了,对10.2.3的那段话理解错误,你们都是对的
浪费各位这么长时间,不好意思........
多谢各位不厌其烦的指点
xiaofan_sap 2009-11-14
  • 打赏
  • 举报
回复
http://blog.csdn.net/xiaofan_sap/archive/2009/10/15/4677394.aspx
看看这篇文章
sdlyczl 2009-11-14
  • 打赏
  • 举报
回复
学习
hzrui 2009-11-14
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 ykl4452 的回复:]
引用 9 楼 hzrui 的回复:
看来楼主对函数理解不深入啊
函数有作用域,还有调用对象,作用域问题是一个链式,一层一层往外找,这个看来你已经知道了

在你的例子中, 没有指明谁调用fn,那么就是 window调用了,我稍微改了一下你的代码,希望你能理解吧

  var outwrap = function(){
            var fn = function(){
                //结果是[object Window]
                alert(this);
            };
fn();

fn.call(this);


this.test = fn;
this.test();

        };
        var o = new outwrap();


是你不理解,类似this.test和fn看似都是相同的方法,但是对于this的解释是截然不同的,不能混为一谈
[/Quote]

我给你加了三句话
fn.call(this);

this.test = fn;
this.test();

用了两种方式显式指明调用对象,函数的this只跟调用对象有关,跟作用域无关,如果没有显式指定调用对象,那么就是windows.

你的fn没有显式指明调用对象,那么就是windows

函数里面的变量分为两种,this.xxx 或是 xxx, 前一种会去调用对象找,后一种会去作用域找

ykl4452 2009-11-14
  • 打赏
  • 举报
回复
你调用fn.call(this); 已经破坏了我的本意,我的本意是想说:fn()内部的this应该指向实例对象o,但实际不是这样,这是为什么呢?因为fn()的调用者——outwrap()构造函数,把null作为this的值传递给fn()。那么更进一步的说,为什么构造函数outwrap()会把null作为this的值传递给fn(),答案就是我在一楼贴的内容
ykl4452 2009-11-14
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 hzrui 的回复:]
看来楼主对函数理解不深入啊
函数有作用域,还有调用对象,作用域问题是一个链式,一层一层往外找,这个看来你已经知道了

在你的例子中, 没有指明谁调用fn,那么就是 window调用了,我稍微改了一下你的代码,希望你能理解吧

var outwrap = function(){
            var fn = function(){
                //结果是[object Window]
                alert(this);
            };
fn();

fn.call(this);


this.test = fn;
this.test();

        };
        var o = new outwrap();

[/Quote]
是你不理解,类似this.test和fn看似都是相同的方法,但是对于this的解释是截然不同的,不能混为一谈
ykl4452 2009-11-14
  • 打赏
  • 举报
回复
to dh20156:冤枉啊,这段我绝对有看,可是和这个的应用场合不太一样
在执行outwrap构造函数的时候,执行fn().
首先,在执行构造函数outwrap()的时候,他内部的this指向谁??毫无疑问,是outwrap的实例对象o,
那么按理来说,fn()的调用者——构造函数outwrap(),应该会把this的值传递给fn(),可是没有。
换句话说,此时的this应该指向outwrap的实例对象o,可是实际却不是如此。

这也是令我非常疑惑的地方,也是10.2.3章节无法解释的,所以才会有这篇帖子和之前那片帖子
hzrui 2009-11-14
  • 打赏
  • 举报
回复
看来楼主对函数理解不深入啊
函数有作用域,还有调用对象,作用域问题是一个链式,一层一层往外找,这个看来你已经知道了

在你的例子中, 没有指明谁调用fn,那么就是 window调用了,我稍微改了一下你的代码,希望你能理解吧

var outwrap = function(){
var fn = function(){
//结果是[object Window]
alert(this);
};
fn();

fn.call(this);


this.test = fn;
this.test();

};
var o = new outwrap();

87,924

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧