JS是一门弱语言,这里的弱语言不是真正意义上的孰强孰弱或是功能是否强大,而是其语法构成的结构不像其他语言那么的规范,就好比说在定义一个数据类型的时候C语言...其他语言就会要求对该变量进行数据类型的声明,不然他就不然认得你当前定义的数据是什么类型,但是JS不同,JS是你定义给它的什么类型,那他就是什么类型,不需要任何多余的其他不同的修饰词来定义它的类型,可以说就是通通"var"搞定,感觉这也是js比较人性化的一点,一定程度上的节省了使用者的脑力资源。
接下来我们说一说JS中的作用域与作用域链,什么是作用域,作用域我们其实可以通俗的理解为以一个区域一个块,就是在该区域,能做的事是什么,又或者说在该区域,受谁的管制,出了区域又受谁的管制,下面我们来一段代码看一下:
var a = 1;
var b = 2;
var c = 3;
function fn(){
console.log(a);//1
console.log(b);//2
console.log(c);//3
}
fn()
//这段代码不难看出结果,必然是上述注释的结果,接下来我就要针对此代码展开对作用域的描述,
//当前的fn函数块就可以看作一块作用域,而外面var a,var b,var c 都是属于全局定义的,什么
//叫全局定义,就是声明后,只要被使用,不论是哪个作用域都会受其影响,这就是全局定义,但是如
//果在其他的作用域范围内重新声明定义了该变量,那当前作用域则会优先选用当前作用域定义声明的
//该变量,只要在当前作用域找不到对应的变量时才会向父级作用域查找直到找到全局为止,全局都还
//找不到那就undefined,这里的undefined是指在定义了但没赋值的情况下,没有定义找对应的变量
//是会直接报错的
- 下面我们针对该代码块做一个延伸,通过代码案例进一步深入作用域及作用域链概念:
var a = 20;
var c = 50;
var b = 60;
function fn(){
console.log(a);//20
// var a = 10;
a = 80;//全局定义
console.log(b);//60
console.log(c);//undefined
var c = b = 100;//当在函数块内对c进行重新赋值的时候,此时没
//有var关键词修饰的b的赋值是全局的,因此并不会影向上面输出的
//语句,但是会影响下面的b的打印输出语句,如果下面再打印输出b
//就会是100的结果
console.log(c)//100
console.log(b)//100
console.log(a);//80
(function(){
console.log(a)//undefined
var a = 20;
console.log(a);//20
a = 120;
console.log(a);//120
console.log(b);//100 b因为 var c = b = 100 在fn函数块被
//全局重定义,所以从该条语句开始往下在全局范围内b的值都会是
//100
console.log(c);//100 这里为什么会输出100呢,首先我们
//看到当前我们是在这个自执行函数里面执行的,而这个自执行
//函数嵌套在函数fn里面,所以当自执行函数体内并没有给c定
//义值,这时候就会向父级去找c有没有被var定义,或者说c有没
//有在全局被重定义,我们找到它的父函数fn,发现他有一条语句
//是var c = b = 100;这个就代表了在fn函数块,c是被fn函数
//块局部重定义了的,而b是全局重定义,他是改变了全局范围内
//的值,所以只要在fn函数块范围内,c在被使用时都会去找到100
//这个值
// var c = b = 200;
// console.log(c);
// a = 30;
})()
}
function z(){
console.log(b)//100 b在fn函数块进行了全局重定义var c = b = 100,
//所以这里的b为100
console.log(c)//50 虽然在fn函数块内有var c = b = 100的语句存在
//但是c前面有var关键词,这就代表c此时仅仅只是在函数块内别重定义只在
//fn函数块这个作用于范围内取值为100,超出fn这个函数块作用域,则会找
//父级作用域是否存在c变量,如果说父级作用域没找到,则继续向上找,找到
//全局为止,这里的50就是最初外面定义的全局的c(var c = 50;)
}
fn()
z()
console.log(b)//100 b在fn函数块进行了全局重定义var c = b = 100,
//所以这里的b为100
console.log(c)//50 虽然在fn函数块内有var c = b = 100的语句存在
//但是c前面有var关键词,这就代表c此时仅仅只是在函数块内别重定义只在
//fn函数块这个作用域范围内取值为100,超出fn这个函数块作用域,则会找
//父级作用域是否存在c变量,如果说父级作用域没找到,则继续向上找,找到
//全局为止,这里的50就是最初外面定义的全局的c(var c = 50;)
总而言之,作用域就是将某事某物圈定在某个范围内,在该范围内,所有的执行行为都会优先考虑自身范围内具有的行为属性,但这并不意味着,在该作用域范围内的执行行为不能参照作用域外的行为属性做出相对应的反应,要知道全局是会影响整个执行行为的,除非说特定的作用域区块内已经有了对应执行行为的行为属性,那该作用域内就会优先调用自身作用域的行为属性,否则找不到对应的行为属性,就会顺着父级作用域一级一级向上找,找到全局为止,倘若全局都还没能有对应的行为属性给到对应的执行行为,那就是undefined,如果连最基本的定义行为都没有的话是直接报错的。


被折叠的 条评论
为什么被折叠?



