JavaScript中作用域和作用域链解析
2016-12-14 12:19
197 查看
科技优家 2016-12-04 16:11
学习js,肯定要学习作用域,js作用域和其他的主流语言的作用域还存在很大的区别。
一.js没有块级作用域。
js没有块级作用域,就像这样:
js中像if,for,switch之类的语句,他们包含的代码块里面的变量,在代码块外面也能被读取,所以说,js没有块级作用域。
二.js的全局变量
js中规定,全局变量都可以看作是window的属性,而且全局变量能够被所有的代码块读取。
虽然在匿名函数中对a没有定义,但是由于a是全局变量,所以其他任何的代码块都能够读取a的值。在一个复杂的项目中,全局变量如果操作不慎,很有可能带来重大的bug。所以在平时写代码的时候,应该尽量避免使用全局变量!对于一个变量来说,如果没有用var来声明的话,那么会自动认为是全局变量,因此,在书写中,一定不能漏写var。
三.js的局部变量
js中的全局变量,很容易使代码存在问题,所以我们应该明确区分全局变量和局部变量!局部变量只在他所在的函数内部读取,在函数外部却无法读取这个变量。
四.js的作用域链问题
由于js存在全局变量和局部变量,在调用一个变量是,会对他的作用域链进行查找,如果函数内部定义了这个变量,那么取该变量的值,如果没有,那么向上一层查找,如果找到了,就获取这个值,如果还没找到,继续往上层查找,直到找到位置,如果找到最后也没找到,那么该变量的值为undefined。
先看一个例子:
先分析一下这个例子,scoap将调用这个函数,第一个console.log(name),会对name的值进行原型链查找,首先看函数scoap内部是否进行了定义,发现在函数内部对name进行了定义,那么第一个console.log(name)将不再往上层查找!那么第一个console.log(name)的值是不是就是“zhixuan”了呢?no!no!no!由于第一个console.log(name)时,对name还没有赋值,所以,第一个console.log(name)为undefined,第二个console.log(name)为“zhixuan”!
再看一个例子:
这次console.log(a)的值为多少呢?首先执行ziben函数,里面定义了a为20,再执行zhixuan函数,要求输出a的值,由于作用域在函数定义的那一瞬间就决定了,所以,zhixuan函数会向上查找到a的全局变量,即var a=10,而不是演着ziben里的作用域查找!所以console.log(a)为10.
学习js,肯定要学习作用域,js作用域和其他的主流语言的作用域还存在很大的区别。
一.js没有块级作用域。
js没有块级作用域,就像这样:
if{ var a = 100; console.log(a) //输出100 } console.log(a) //输出100
js中像if,for,switch之类的语句,他们包含的代码块里面的变量,在代码块外面也能被读取,所以说,js没有块级作用域。
二.js的全局变量
js中规定,全局变量都可以看作是window的属性,而且全局变量能够被所有的代码块读取。
var a = 10; function { b = 20; console.log(a); //输出10; } console.log(b); //输出20;
虽然在匿名函数中对a没有定义,但是由于a是全局变量,所以其他任何的代码块都能够读取a的值。在一个复杂的项目中,全局变量如果操作不慎,很有可能带来重大的bug。所以在平时写代码的时候,应该尽量避免使用全局变量!对于一个变量来说,如果没有用var来声明的话,那么会自动认为是全局变量,因此,在书写中,一定不能漏写var。
三.js的局部变量
js中的全局变量,很容易使代码存在问题,所以我们应该明确区分全局变量和局部变量!局部变量只在他所在的函数内部读取,在函数外部却无法读取这个变量。
function doSomething{ var blogName="智轩资本"; function innerSay{ alert(blogName); } innerSay; } alert(blogName); //undefined innerSay; //undefined
四.js的作用域链问题
由于js存在全局变量和局部变量,在调用一个变量是,会对他的作用域链进行查找,如果函数内部定义了这个变量,那么取该变量的值,如果没有,那么向上一层查找,如果找到了,就获取这个值,如果还没找到,继续往上层查找,直到找到位置,如果找到最后也没找到,那么该变量的值为undefined。
先看一个例子:
var myName = '智轩资本'; function scoap { console.log(myName); var myName = "zhixuan"; console.log(myName); console.log(age); } scoap;
先分析一下这个例子,scoap将调用这个函数,第一个console.log(name),会对name的值进行原型链查找,首先看函数scoap内部是否进行了定义,发现在函数内部对name进行了定义,那么第一个console.log(name)将不再往上层查找!那么第一个console.log(name)的值是不是就是“zhixuan”了呢?no!no!no!由于第一个console.log(name)时,对name还没有赋值,所以,第一个console.log(name)为undefined,第二个console.log(name)为“zhixuan”!
再看一个例子:
var a = 10; function zhixuan { console.log(a); } function ziben { var a = 20; zhixuan; } ziben;
这次console.log(a)的值为多少呢?首先执行ziben函数,里面定义了a为20,再执行zhixuan函数,要求输出a的值,由于作用域在函数定义的那一瞬间就决定了,所以,zhixuan函数会向上查找到a的全局变量,即var a=10,而不是演着ziben里的作用域查找!所以console.log(a)为10.
相关文章推荐
- 深入理解JavaScript作用域和作用域链
- 深入理解JavaScript作用域和作用域链
- JavaScript作用域与作用域链深入解析
- javascript中的作用域和作用域链
- JavaScript 作用域链解析
- 深入理解JavaScript作用域和作用域链
- JavaScript中的作用域和作用域链(二)
- 深入解析JavaScript中的变量作用域
- JavaScript作用域与作用域链深入解析
- JavaScript 作用域链解析
- javascript笔记:深入了函数的作用域链及标识符解析的过程
- 理解JavaScript作用域和作用域链
- 深入理解JavaScript作用域和作用域链
- 深入解析JavaScript中的变量作用域
- 深入理解javascript作用域和作用域链
- JavaScript 作用域链解析
- 深入理解JavaScript作用域和作用域链
- JavaScript 作用域链解析
- JavaScript 作用域链解析
- JavaScript中的作用域和作用域链(一)