js 函数作用域, 块级作用域和词法作用域
Posted shuajing
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js 函数作用域, 块级作用域和词法作用域相关的知识,希望对你有一定的参考价值。
函数作用域, 块级作用域和词法作用域
0 作用域:
0.1 作用域是程序源代码中定义变量的区域。
0.2 作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限。
0.3 ECMAScript6之前只有全局作用域和函数作用域。
0.4 javascript采用词法作用域(lexical scoping),也就是静态作用域。
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f();
}
checkscope(); //local scope
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f;
}
checkscope()();//local scope
1 变量作用域:全局变量和局部变量
var a=1; //全局变量
function B(){
alert(a);
}
function B(){
var c=1; //局部变量
alert(c);
}
function C(){
d=1; //全局变量
alert(d);
}
d;//1
2 闭包:就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
2.1 用途:以读取函数内部的变量;让这些变量的值始终保持在内存中。
function f1(){
var count=6;
add=function(){
count+=1;
}
function f2(){
console.log(count);
}
return f2;
}
var f=f1();
f();//6
add();
f();//7
原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收
2.2 注意点:
2.2.1 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2.2.2 闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
3 词法作用域
3.1 一般来说,在编程语言里我们常见的变量作用域就是词法作用域与动态作用域(Dynamic Scope),绝大部分的编程语言都是使用的词法作用域。词法作用域注重的是所谓的Write-Time,即编程时的上下文,而动态作用域以及常见的this的用法,都是Run-Time,即运行时上下文。词法作用域关注的是函数在何处被定义,而动态作用域关注的是函数在何处被调用。JavaScript是典型的词法作用域的语言,即一个符号参照到语境中符号名字出现的地方,局部变量缺省有着词法作用域。
function foo() {
console.log( a ); // 2 in Lexical Scope ,But 3 in Dynamic Scope
}
function bar() {
var a = 3;
foo();
}
var a = 2;
bar();
以上是关于js 函数作用域, 块级作用域和词法作用域的主要内容,如果未能解决你的问题,请参考以下文章