深入理解函数的作用域
来源:互联网 发布:mac装windows虚拟机 编辑:程序博客网 时间:2024/05/16 12:40
一、作用域(scope)
所谓作用域就是:变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。
1 function scope(){ 2 var foo = "global"; 3 if(window.getComputedStyle){ 4 var a = "I'm if"; 5 console.log("if:"+foo); //if:global 6 } 7 while(1){ 8 var b = "I'm while"; 9 console.log("while:"+foo);//while:global10 break;11 }12 !function (){13 var c = "I'm function";14 console.log("function:"+foo);//function:global15 }();16 console.log(17 foo,//global18 a, // I'm if19 b, // I'm while20 c // c is not defined21 );22 }23 scope();
(1)scope函数中定义的foo变量,除过自身可以访问以外,还可以在if语句、while语句和内嵌的匿名函数中访问。 因此,foo的作用域就是scope函数体。
(2)在javascript中,if、while、for 等代码块不能形成独立的作用域。因此,javascript中没有块级作用域,只有函数作用域。
但是,在JS中有一种特殊情况:
如果一个变量没有使用var声明,window便拥有了该属性,因此这个变量的作用域不属于某一个函数体,而是window对象。
1 function varscope(){2 foo = "I'm in function";3 console.log(foo);//I'm in function4 }5 varscope();6 console.log(window.foo); //I'm in function
二、作用域链(scope chain)
所谓作用域链就是:一个函数体中嵌套了多层函数体,并在不同的函数体中定义了同一变量, 当其中一个函数访问这个变量时,便会形成一条作用域链(scope chain)。
1 foo = "window"; 2 function first(){ 3 var foo = "first"; 4 function second(){ 5 var foo = "second"; 6 console.log(foo); 7 } 8 function third(){ 9 console.log(foo);10 }11 second(); //second12 third(); //first13 }14 first();
当执行second时,JS引擎会将second的作用域放置链表的头部,其次是first的作用域,最后是window对象,于是会形成如下作用域链:
second->first->window, 此时,JS引擎沿着该作用域链查找变量foo, 查到的是"second"
当执行third时,third形成的作用域链:third->first->window, 因此查到的是:"frist"
特殊情况:with语句
JS中的with语句主要用来临时扩展作用域链,将语句中的对象添加到作用域的头部。with语句结束后,作用域链恢复正常。
1 foo = "window"; 2 function first(){ 3 var foo = "first"; 4 function second(){ 5 var foo = "second"; 6 console.log(foo); 7 } 8 function third(obj){ 9 console.log(foo); //first10 with (obj){11 console.log(foo); //obj12 }13 console.log(foo); //first14 }15 var obj = {foo:'obj'};16 third(obj);17 }18 first();
在执行third()时,传递了一个obj对象,obj中有属性foo, 在执行with语句时,JS引擎将obj放置在了原链表的头部,于是形成的作用域链如下:
obj->third->first->window, 此时查找到的foo就是obj中的foo,因此输出的是:"obj", 而在with之前和之后,都是沿着原来的链表进行查找,从而说明,在with语句结束后,作用域链已恢复正常。
三、this 关键字
在一个函数中,this总是指向当前函数的所有者对象,this总是在运行时才能确定其具体的指向, 也才能知道它的调用对象。
这句话总结了关于this的一切,切记,切记,切记!(ps:重要的事情说三遍!)
1 window.name = "window";2 function f(){3 console.log(this.name);4 }5 f();//window6 7 var obj = {name:'obj'};8 f.call(obj); //obj
在执行f()时,此时f()的调用者是window对象,因此输出"window"
f.call(obj) 是把f()放在obj对象上执行,相当于obj.f(),此时f中的this就是obj,所以输出的是"obj"
四、实战应用
code1:
1 var foo = "window"; 2 var obj = { 3 foo : "obj", 4 getFoo : function(){ 5 return function(){ 6 return this.foo; 7 }; 8 } 9 };10 var f = obj.getFoo();11 f(); //window
code2:
var foo = "window";var obj = { foo : "obj", getFoo : function(){ var that = this; return function(){ return that.foo; }; }};var f = obj.getFoo();f(); //obj
- 深入理解函数的作用域
- 深入理解javascript函数定义与函数作用域
- 深入理解javascript函数定义与函数作用域
- 深入理解JavaScript的变量作用域
- 深入理解JavaScript的变量作用域
- 深入理解JavaScript的变量作用域
- 深入理解JavaScript的变量作用域
- 深入理解JavaScript的变量作用域
- 深入理解JavaScript的变量作用域
- 深入理解JavaScript的变量作用域
- 深入理解JavaScript的变量作用域
- javaScript的作用域链深入理解
- 深入理解JavaScript的变量作用域
- 深入理解JavaScript的变量作用域
- 深入理解JavaScript的变量作用域
- 深入理解JavaScript的变量作用域
- 深入理解JavaScript的变量作用域
- JavaScript的变量作用域深入理解
- 欢迎使用CSDN-markdown编辑器
- 【UE4】 第09讲 【MOBA制作日记】 隐藏默认创建的DefaultPawn
- 九宫格问题
- ImageNet Classification with Deep Convolutional Neural Networks简介
- poj1195 Mobile phones(二维树状数组)
- 深入理解函数的作用域
- 1007. 素数对猜想 (20)
- 运算符重载-编程题#2(C++程序设计第4周)
- 索引综述
- Bellman-Ford的队列优化
- UVA 10214 Trees in a Wood. (欧拉函数)
- Servlet
- MySQL职工管理系统
- python GUI编程(Tkinter)