function变量困惑
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变量困惑的更多相关文章
- this指针与function变量--this究竟指向哪里?
参考文章:<深入浅出 JavaScript 中的 this> http://www.ibm.com/developerworks/cn/web/1207_wangqf_jsthis/ Ja ...
- 六天玩转javascript:javascript变量与表达式(1)
说明 本系列属于进阶系列,语常用语法等不在本系列介绍范围之内. 在我刚开始做一个程序员并开发项目的时候,我总是喜欢使用开发语言的各种特性,每次m$发布新版C#的时候我总是会把开发者预览版下好,亲自体验 ...
- 在javascript中关于变量与函数的提升
在javascript中关于变量与函数的提升 一.简介 在javascript中声明变量与函数的执行步骤: 1.先预解析变量或函数声明代码,会把用var声明的变量或者函数声明的代码块进行提升操作 2. ...
- js变量和函数声明的提升
函数声明和变量声明总是会被解释器悄悄地被“提升”到方法体的最顶部 请注意,变量赋值并没有被提升,只是声明被提升了. 函数的声明比变量的声明具有高的优先级. 下面的程序是什么结果? var foo = ...
- JS基础——变量
引用类型:对象 数组 函数 }; var b =a ; b.age = ; console.log(a.age);// 21 传递的是地址, a,b同地址 值类型: var a =100; var ...
- js变量和函数声明的提升(转)
原文:http://zha-zi.iteye.com/blog/2037026 下面的程序是什么结果? var foo = 1; function bar() { if (!foo) { var fo ...
- [转]js 判断js函数、变量是否存在
本文转自:http://blog.csdn.net/liang4571231/article/details/4042519 在进行js编程时,总会出现可能一些函数或者变量未定义而被引用,导致报错的情 ...
- JavaScript变量提升 面试题
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...
- Javascript作用域和变量提升
下面的程序是什么结果? var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar(); 结果是10: 那么 ...
随机推荐
- Python模块之"prettytable"
Python模块之"prettytable" 摘要: Python通过prettytable模块可以将输出内容如表格方式整齐的输出.(对于用Python操作数据库会经常用到) 1. ...
- WEB端实现打印
首先需要下载一个JQ插件: 地址: http://files.cnblogs.com/files/SabWoF/jq%E6%89%93%E5%8D%B0%E6%8F%92%E4%BB%B6%E5%AE ...
- CentOS7 学习笔记
1.首先centos7 采用了systemd管理系统服务的启动 systemd结合了以前红帽子的service 与chkconfig systemctl [command] [unit] comm ...
- css清除浮动大全共8种方法
原文链接http://www.jb51.net/css/173023.html 清除浮动是每一个 web前台设计师必须掌握的机能.css清除浮动大全,共8种方法. 浮动会使当前标签产生向上浮的效果,同 ...
- 把包发布到npm官网
一.包 包就是多模块的集合,CommonJS的包规范给程序员提供了组织模块的标准,减少沟通成本. 规范: 所有的模块放在demo文件夹下(包名)的lib文件夹里面 在lib文件夹的同级目录下新建ind ...
- 深入HashMap
HashMap: 内部基于数组和单向链表 重要的变量有: Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE:结点数组table中存 ...
- request:getParameter getAttribute
转载自:http://www.cnblogs.com/shaohz2014/p/3804656.html 在浏览器地址输入,表示传入一个参数test,值为123 http://localhost:88 ...
- java.io.EOFException
错误代码如下: 严重: IOException while loading persisted sessions: java.io.EOFException java.io.EOFException ...
- Google之Chromium浏览器源码学习——base公共通用库(一)
Google的优秀C++开源项目繁多,其中的Chromium浏览器项目可以说是很具有代表性的,此外还包括其第三开发开源库或是自己的优秀开源库,可以根据需要抽取自己感兴趣的部分.在研究.学习该项目前的时 ...
- POJ 3669 Meteor Shower【BFS】
POJ 3669 去看流星雨,不料流星掉下来会砸毁上下左右中五个点.每个流星掉下的位置和时间都不同,求能否活命,如果能活命,最短的逃跑时间是多少? 思路:对流星雨排序,然后将地图的每个点的值设为该点最 ...