javascript作用域和作用域链详解

 更新时间:2022年01月23日 15:41:14   作者:卖菜的小白  
这篇文章主要为大家介绍了javascript作用域和作用域链,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

一、javascript的作用域

1、全局作用域

1、最外层函数和最外层函数定义的变量
var age = 20
function func1() {
  var sex = "男"
  function func2() {
    console.log("hello func2")
  }
  func2()
}
console.log(age)    //20
console.log(func1)  //正常执行
console.log(func2)  //报错
console.log(sex)    //报错
2、所有未直接声明的变量,直接赋值为全局变量
function func1() {
  var age = 20
  sex = "男"
}
func1()
console.log(sex)    //男
console.log(age)    //报错
3、window对象上面的属性具有全局作用域
function func1() {
  var age = 20
  sex = "男"
  console.log(top)   //window....
  
}
func1()
console.log(sex)   //"男"
console.log(top)   //window....

2、局部作用域

和全局作用域相反,局部作用域只在函数内部可以访问到。function func1() {  var age = 20  func1()  function func1() {    console.log("func1")  }}func1()和全局作用域相反,局部作用域只在函数内部可以访问到。
function func1() {
  var age = 20
  func1()

  function func1() {
    console.log("func1")
  }
}
func1()

二、javascript的作用域链

函数也是对象,在函数内部存在一个属性[[scope]],该属性包含可以访问属性的集合。决定了哪些属性在函数中可以访问到。
下面我们以一个函数的例子来详细解说一下,函数作用域链。
1、在函数函数创建出来时。代码如下所示
function add(num1, num2) {
  return num1 + num2
}

在这里插入图片描述

函数初始化时,会将自己的作用域链中放入全局变量
var total = add(10, 20)
这里是函数执行时,当执行时会创建一个新的对象放入作用域链中,这个对象中包括
arguments, 形参,this,以及返回值。

在这里插入图片描述

active object是活跃对象,是函数执行时创建的对象,然后scope chain类似于栈结构,函数执行前压入栈中,函数执行结束就从栈中弹出。函数访问属性的过程就是沿着scope chain从上往下一次查找。

三、作用域链和优化

从上面的例子中,我们可以看出,访问全局作用域是最慢的,因为需要依次从上往下进行查找,应当尽可能少的使用全局变量,应该尽可能使用局部变量。如果在函数
中,使用多次全局变量,我们可以将全局变量转化为局部变量,然后在使用局部变量。
function changeColor(){
    document.getElementById("btnChange").onclick=function(){
        document.getElementById("targetCanvas").style.backgroundColor="red";
    };
}
上面代码我们使用了两次document,但是document作为全局变量,此时我们应该将其转化为局部变量来使用,所以下面为转化后的代码。
function changeColor(){
    var doc=document;
    doc.getElementById("btnChange").onclick=function(){
        doc.getElementById("targetCanvas").style.backgroundColor="red";
    };
}

四、改变作用域链

1、with语法改变作用域链

with语法的作用就是为了解决代码重写问题,是对象快捷书写方式,但是这么好的方式,为什么不大力推广使用呢?因为性能存在一些问题。function initUI(){    with(document){        var bd=body,            links=getElementsByTagName("a"),            i=0,            len=links.length;        while(i < len){            update(links[i++]);        }        getElementById("btnInit").onclick=function(){            doSomething();        };    }}这里使用with语法省略了document。with语法的作用就是为了解决代码重写问题,是对象快捷书写方式,但是这么好的方式,为什么不大力推广使用呢?
因为性能存在一些问题。
function initUI(){
    with(document){
        var bd=body,
            links=getElementsByTagName("a"),
            i=0,
            len=links.length;
        while(i < len){
            update(links[i++]);
        }
        getElementById("btnInit").onclick=function(){
            doSomething();
        };
    }
}
这里使用with语法省略了document。

在这里插入图片描述

with传入的对象的属性放入最上层,剩余的都往下压,导致局部变量的访问代价增大,所以with的性能不好。

2、catch语法

我们在使用try--catch时,当代码执行错误时,会执行catch函数,catch函数中参数是错误对象,就是这个错误对象,会放到作用域链的头部。
但是try--catch我们在必要的使用得使用,我们可以这样解决。
try{
    doSomething();
}catch(ex){
    alert(ex.message); //作用域链在此处改变
}

处理后:
try{
    doSomething();
}catch(ex){
    handleError(ex); //委托给处理器方法
}
解决方案是:将catch错误处理交给另外一个函数进行处理。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

相关文章

  • js函数在frame中的相互调用详解

    js函数在frame中的相互调用详解

    一个HTML页面可以有一个或多个子框架,这些子框架以<iframe>来标记,用来显示一个独立的HTML页面。这里所讲的框架编程包括框架的自我控制以及框架之间的互相访问,例如从一个框架中引用另一个框架中的JavaScript变量、调用其他框架内的函数、控制另一个框架中表单的行为等
    2014-03-03
  • 浅谈JavaScript Array对象

    浅谈JavaScript Array对象

    这篇文章主要介绍了JavaScript Array对象的相关资料,需要的朋友可以参考下
    2014-12-12
  • js中对象深拷贝方法总结

    js中对象深拷贝方法总结

    js深拷贝这个问题,在实际的工作和面试当中也是经常使用到的。
    还经常有一些公司要求,原生手写实现,这篇文章主要介绍了js中对象深拷贝方法总结,需要的朋友可以参考下
    2022-10-10
  • JS中switch的四种写法示例

    JS中switch的四种写法示例

    这篇文章主要为大家介绍了JS中switch的四种写法示例代码,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • js中常用的弹出对话框3种方式

    js中常用的弹出对话框3种方式

    javascript下自带的三个弹出对话框效果,需要的朋友可以参考下。下面对各个函数的说明也有使用用途,
    2010-08-08
  • JavaScript中void(0)的具体含义解释

    JavaScript中void(0)的具体含义解释

    JavaScript中void(0)的具体含义解释...
    2007-02-02
  • 浅谈JavaScript的对象类型之function

    浅谈JavaScript的对象类型之function

    这篇文章主要介绍了浅谈JavaScript的对象类型之function,函数(方法)是由事件驱动的或者当它被调用时执行的可重复使用的代码块,需要的朋友可以参考下
    2023-05-05
  • 浅谈Javascript中匀速运动的停止条件

    浅谈Javascript中匀速运动的停止条件

    这篇文章主要给我们探讨了Javascript中匀速运动的停止条件的原理及其与缓冲运动的区别,需要的朋友可以参考下
    2014-12-12
  • 每个程序员都需要学习 JavaScript 的7个理由小结

    每个程序员都需要学习 JavaScript 的7个理由小结

    这篇文章主要介绍了每个程序员都需要学习 JavaScript 的7个理由小结,需要的朋友可以参考下
    2016-09-09
  • 详解在网页上通过JS实现文本的语音朗读

    详解在网页上通过JS实现文本的语音朗读

    这篇文章主要介绍了在网页上通过JS实现文本的语音朗读,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03

最新评论