var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};

一个经典的代码,在高程也出现过的,意在说明 this 和 闭包变量作用域。

以前写过一篇记录一下,最近在sf看到一博客文章,又突然陷入深思。

http://blog.segmentfault.com/findingea/1190000000537129

首先,说一下2个关键点:

1.function的作用域:在function中访问一变量,首先看function执行体内是否存在该变量,不存在,则往function的调用环境,去查询,如果是多层调用,则会遵循内部找不到就往外部查找,一直到全局作用域,这也就是作用域链。

1.1一般说来,闭包,即内部函数调用了外部函数的变量,并返回自身给外部使用,此时,即可访问到外部函数的变量,这里能不能说其实也是套用了所谓的作用域链原理呢。

2. function的作用域内,本身执行体的执行环境包含参数arguments和this两个自带的,不会导致需要去外部找变量,上面的经典问题中,this.name之所以返回的是 the window 即全局变量,那是因为function自身的调用环境决定的,这个return的闭包,不属于object对象本身的属性,因此,自然而然,其调用主题是全局window。

通过需要后,即可达到访问object.name的效果.

 var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
}
};

这里用that存了this,getNameFunc本身就是object的属性,因此this指向的是object,而that作为最底层的function的外部函数的作用域之一,刚好function内部没有that的申明,所以自然内部调用that访问的就是外部函数的作用域的that。

而我本来觉得这样好理解,突然想,那么不要this呢?

 var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return name;
};
}
};

一开始以为,根据作用域链,最终得到的name应该是object.name,结果一运行,不对,为什么呢?

一开始搞不明白。

但是,回想起来,首先,getNameFunc这里如果调用name同样得到的是全局的name.  想想,假设我加一句代码进去,

 var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
console.log(name); //这里name是全局name
return function(){
return name;
};
}
};

正如我注释的那里,这里直接调用name,跟调用this.name的不同,在于this.name是对象的属性,直接调用,则是查找作用域里声明的name,明显与对象属性不是同一个概念,正如

var name = 0; 和 obj.name="dont"; 不能相提并论,不知道这么解释对不对。

也正因为作用域里不存在独立的name声明,因此最终找到的是全局的作用域声明的name: The Window.

function变量困惑的更多相关文章

  1. this指针与function变量--this究竟指向哪里?

    参考文章:<深入浅出 JavaScript 中的 this> http://www.ibm.com/developerworks/cn/web/1207_wangqf_jsthis/ Ja ...

  2. 六天玩转javascript:javascript变量与表达式(1)

    说明 本系列属于进阶系列,语常用语法等不在本系列介绍范围之内. 在我刚开始做一个程序员并开发项目的时候,我总是喜欢使用开发语言的各种特性,每次m$发布新版C#的时候我总是会把开发者预览版下好,亲自体验 ...

  3. 在javascript中关于变量与函数的提升

    在javascript中关于变量与函数的提升 一.简介 在javascript中声明变量与函数的执行步骤: 1.先预解析变量或函数声明代码,会把用var声明的变量或者函数声明的代码块进行提升操作 2. ...

  4. js变量和函数声明的提升

    函数声明和变量声明总是会被解释器悄悄地被“提升”到方法体的最顶部 请注意,变量赋值并没有被提升,只是声明被提升了. 函数的声明比变量的声明具有高的优先级. 下面的程序是什么结果? var foo =  ...

  5. JS基础——变量

    引用类型:对象  数组 函数 }; var b =a ; b.age = ; console.log(a.age);// 21 传递的是地址, a,b同地址 值类型: var a =100; var ...

  6. js变量和函数声明的提升(转)

    原文:http://zha-zi.iteye.com/blog/2037026 下面的程序是什么结果? var foo = 1; function bar() { if (!foo) { var fo ...

  7. [转]js 判断js函数、变量是否存在

    本文转自:http://blog.csdn.net/liang4571231/article/details/4042519 在进行js编程时,总会出现可能一些函数或者变量未定义而被引用,导致报错的情 ...

  8. JavaScript变量提升 面试题

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  9. Javascript作用域和变量提升

    下面的程序是什么结果? var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar(); 结果是10: 那么 ...

随机推荐

  1. PowerDesigner通过SQL语句生成PDM文件

    前提: 我用的是PowerDesigner15 数据库为Mysql5.5 步骤如下: 第一步:File->New Model 点击OK创建模板就行了 备注:在创建物理模型时DBMS下拉框是空的, ...

  2. centos6u3 安装 celery 总结

    耗时大概6小时. 执行 pip install celery 之后, 在 mac 上 celery 可以正常运行, 在 centos 6u3 上报错如下: Traceback (most recent ...

  3. iOS 事件传递(Touch事件)

    先总说如下: 1.当手指触摸到屏幕时,会产生UITouch对象和UIEvent对象. 2.这两个对象产生后会被传递到UIApplication管理的一个事件队列中. 3.再有UIApplication ...

  4. Photoshop 裁剪图片

    如图1选择裁剪工具,然后如图2点一下clear,就可以根据鼠标裁剪任意大小的图片

  5. js与jq对数组的操作

    一.数组处理 1.数组的创建  var arrayObj = new Array(); //创建一个数组  var arrayObj = new Array([size]); //创建一个数组并指定长 ...

  6. hibernate映射文件

    Hibernate的持久化类和关系数据库之间的映射通常是用一个XML文档来定义的.该文档通过一系列XML元素的配置,来将持久化类与数据库表之间建立起一一映射.这意味着映射文档是按照持久化类的定义来创建 ...

  7. div不换行_div同行_div强制不换行

    使用Float <!--已知两个div的宽度使用[Float]使两个DIV同行!注:float使用后需要清除:所以多写一个div--> <div style="width: ...

  8. SQL Server 2012 开发新功能 序列对象(Sequence)(转)

    转载链接:http://www.cnblogs.com/zhangyoushugz/archive/2012/11/09/2762720.html 众所周知,在之前的sqlserver版本中,一般采用 ...

  9. RedHat Enterprise Linux 6.4 使用 Centos 6 的yum(转)

    概述 redhat的yum源需注册付费,费时费力,整理RedHat yum 安装CentOS的方法. 安装系统文件 系统:RedHat Enterprise Linux 6.4-x86_64 md5: ...

  10. JSON对象格式美化

    JSON.stringify(obh, null, "\t"); 这段代码就可以对某个js对象美化输出