JS作用域

来源:互联网 发布:数控铣床编程简单实例 编辑:程序博客网 时间:2024/06/07 21:05

JS作用域理解

看书总结的个人理解,欢迎指正,共同进步~~

JavaScript被归类为解释执行的编译语言, JavaScript采用的是词法作用域原型,在代码编写时,作用域就确定下来.学过编译可知,会在源程序运行边解释边运行,类比”口译”,但js中提供了在词法分析后依旧可以修改作用域的方法:


  • eval( )函数 在参数中修改的函数,被动态加入修改作用域

function print(a,b){    eval(a);    console.log(a,b)}var c=2;print("var c=1",10);   //1 10

  • with 关键字 with(obj){…}
  • 为obj创建新的作用域,若obj没有{}内部的属性k, obj.k值为undefined不会创建新属性,非严格模式下会创建全局属性.

    以上两种方法会导致性能下降,很难优化.

    作用域

    ES5中只全局和函数级作用域
    基于最小暴露原则,我们通过匿名函数(不具名可减少对全局的污染),立即执行函数(IIFE)将代码包装起来.在ES6中,引入块级作用域

    • let声明:之前只有var 和 function声明 使用let后,将变量绑定到let所在{}内部
    • with :上面有提到
    • try/catch中:  在catch分句内部声明的仅在其中有效
    • const:  注意声明一个常量不可再更改,声明时即赋值.const声明的对象为地址时,要保证地址不变,但可以修改对象.

    通过块级作用域,可以不使用IIFE~~
    要注意const和let没有声明提升;且不可重复声明,会报错.

    提升

    • 函数,var定义的变量声明会提升,但赋值操作不会,执行时通过LHS找到目标才操作.
    • 函数声明未定义,导致ReferenceError;未声明则是TypeError.
    • 以function开始,被认为是函数声明,可以提升,而其他被认为是函数表达式,不提升导致不是一个函数(typeError)

    关于this

    this是运行才会绑定对象,动态变化的,但首先明确this翻译是这个,但”这个”并非函数本身,在<<你不知道的JavaScript>>中看到一个有意思的例子

    function foo(){  var a=2;  this.bar();}function bar(){    console.log(this.a);}foo()        //ReferenceError a is not defined

    错误:
    1.为了让bar的this指向自身,foo()错误地在bar()前面加了this.这里可以直接调用
    2.bar函数内部使用this使用foo的a变量,但作用域不可以通过js联通访问,可以当作参数传递.

    0 0