JavaScript 的作用域和作用域链。在初学 JavaScript 时,觉得它就和其他语言没啥区别,尤其是作用域这块,想当然的以为 "全局变量就是在整个程序的任何地方都可以访问,也就是写在函数外的变量,局部变量也就是写在函数内部或循环体内部,出了循环体和函数就不可访问",但是在 JavaScript 中并不是这么简单,需要去深入的学习。
一. 什么是作用域
任何程序语言都有作用域的概念,简单的说,作用域就是变量与函数的可访问范围。比如 C/C++ 等,都是块级作用域,也就是说在每一个代码块内声明的变量,出了这个代码块就是不可见的,而 JS 根本就没有块级作用域这个概念,而是函数作用域。如下面的例子:
- function test() {
- var sum = 0;
- for (var i = 0; i < 2; i++) {
- sum = sum + i;
- }
- console.log(i);
- }
- test();
二. 函数作用域
看到上面的小例子,应该对函数作用域有一点模糊的理解吧。其实也就是说,变量和函数在声明它们的函数体中,和这个函数体嵌套的任意函数体内部都是可访问的。下面再看个小例子:
- function test() {
- var name = "xiyangyang";
- function showname() {
- console.log(name);
- }
- showname();
- }
- test(); //xiayangyangshowname(); //ReferenceError: showname is not defined
三. 变量作用域
JS 的变量计较特殊,下面是一些小例子,请看它的特殊点:
(1)全局变量被覆盖:
- var name = "huitaiyang"
- function test() {
- console.log(name);
- var name = "xiyangyang";
- console.log(name);
- }
- test();
(2)没有 var 声明的局部变量,上升为全局变量:
- function test() {
- name = "xiyangyang";
- console.log(name);
- }
- test();
- console.log(name);
四. 作用域链
一旦函数创建,函数的作用域就确定了,作用域链就由作用域中对象的集合组成。当函数执行时,它会把当前正在执行的函数内部的所有变量(包括 this)置于作用域链的首部,会把该函数外部的对象置于第二,第三… 层,window 对象置于最外层。作用域链的层数和函数的层数有关。
- var name = "huitaiyang"
- function test() {
- var name = "xiyangyang";
- function show1() {
- var name = "lanyangyang";
- console.log(name);
- }
- function show2() {
- console.log(name);
- }
- show1();
- show2();
- }
- test();
五. 作用域链和代码优化
看完上面的所有内容的同学就会很容易理解这里,如下这个小例子:
- function changeColor() {
- document.getElementById('btn').onclick = function() {
- document.getElementById('obj').style.backgroundColor = 'red';
- };
- }
大家都知道 document 是全局变量,也就是在作用域链的最尾部,查找是很消耗资源的,所以需要优化,优化后代码为:
- function changeColor() {
- var doc = document;
- doc.getElementById('btn').onclick = function() {
- doc.getElementById('obj').style.backgroundColor = 'red';
- };
- }
这样找一次就够了,所以当一个对象被跨作用域访问时,可以把它存储为局部变量使用,这样就起到了优化的作用。
六. 修改作用域链
这里就简单的提一下,能理解就有好了,with 和 catch 会修改函数的作用域链。
(1)如果代码块中有 with,则 with 中的所有对象会置于当前作用域链的最顶层,当前函数会被置于第二层。会降低代码的性能,所以不推荐使用。
(2)catch 语句会把异常对象置于作用域链的顶部,当前执行函数会被置于第二层。同样影响代码的性能。
就爱阅读 www.92to.com 网友整理上传, 为您提供最全的知识大全, 期待您的分享,转载请注明出处。
来源: http://www.92to.com/bangong/2017/02-28/17833673.html