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. excel链接sharepoint 用于 Excel 的 Microsoft Power Query

    https://www.microsoft.com/zh-cn/download/confirmation.aspx?id=39379

  2. jQuery根据name取input值问题

    最近做项目用$("input[name=inputName]").val();去取input值得时候发现取值有问题:总是取第一次输入的值,如果在同一个页面不发生表单提交,然后将in ...

  3. 关于easyui datagrid 表格数据处理

    首先先将easyui 引入到jsp页面中 <link rel="stylesheet" type="text/css" href="easyui ...

  4. 安装两个tomcat

    编辑环境变量:vi /etc/profile 加入以下代码(tomcat路径要配置自己实际的tomcat安装目录) ##########first tomcat########### CATALINA ...

  5. (转)java redis使用之利用jedis实现redis消息队列

    应用场景 最近在公司做项目,需要对聊天内容进行存储,考虑到数据库查询的IO连接数高.连接频繁的因素,决定利用缓存做. 从网上了解到redis可以对所有的内容进行二进制的存储,而java是可以对所有对象 ...

  6. Riemann映射定理

    单复变函数几何理论最高的成就我想应该属于Riemann映射定理吧! Riemann映射定理:$\mathbb C$中任意边界多余一个点的单连通域$D$都与单位圆盘$B(0,1)$等价,即存在着$D$上 ...

  7. 获取json数据

    通过异步获取json来展示数据表格,性能提高不少.实例如下: 前台: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999 ...

  8. url地址的图片路径

    url地址的图片路径: (./images/1.jpg) 中的./指根路径,有或没有都可以: (../images/1.jpg) 中的../指相对路径: (../../images/1.jpg) 中的 ...

  9. tensorflow中的lstm的state

        考虑 state_is_tuple     Output, new_state = cell(input, state)     state其实是两个 一个 c state,一个m(对应下图的 ...

  10. C语言的可变参数在Linux(Ubuntu)与Windows下注意点

    基本上C语言的可变参数原理在不同平台和不同编译器下基本类似(通过函数入栈,从右向左,从高位到低位地址),不过部分实现会有所不同:在使用中需要注意的是: va_list 为char 类型指针,部分调用如 ...