nicoleJT914 / blog

一只游行的火烈鸟/用issues记博客
0 stars 0 forks source link

作用域 #6

Open nicoleJT914 opened 7 years ago

nicoleJT914 commented 7 years ago

明明当时看的时候觉得很清楚,为什么会忘得这么快!只能重新回顾记笔记防老了。。。

作用域

在尝试把自己之前写的效果写成组件时,发现自己还是会因为作用域问题产生疑惑,在这里总结一下

  1. 当一个程序引入多个第三方库时,如果没有将各个库私有的变量或函数隐藏起来,很容易引发变量冲突。 避免冲突一种常见解决方式:使用库的命名空间。
    var myOwnLibrary = {
    name: 'xiaoMing',
    doSomething: function() {
    // ...
    }
    }

    这样暴露给外界的变量就变为myOwnLibrary的属性

另外一种解决方式就是 模块管理 使用这些工具,任何库都无需将标识符加入到全局作用域中,而是通过依赖管理器的机制将库的标识符显式地导入到另外一个特定的作用域中。(还不了解模块管理机制,暂且将书中原话粘过来)

  1. IIFE 函数立即执行表达式 IIFE在UMD中很常见的一种模式

    var a = 2;
    (function IIFE( def ) { 
    def( window );
    })(function def( global ) {
    var a = 3;
    console.log( a ); // 3
    console.log( global.a ); // 2
    });

    以上形式其实等价于

    var a = 2;
    (function IIFE (global) {
    var a = 3
    console.log(a)  // 3
    console.log(global.a)  // 2
    }) (window)
    console.log(a)  // 2

    只是上面是将需要执行的函数当做参数传了进去

  2. 劫持块作用域 ES6新引入的关键字letconst可以允许声明一个限制在块作用域中的变量 需要注意的是letconst不会在块作用域中进行提升

let与for循环

for (let i=0; i<10; i++) { 
  console.log( i );
}
console.log( i ); // ReferenceError

for 循环头部的let不仅将 i 绑定到了 for 循环的块中,事实上它将其重新绑定到了循环的每一个迭代中,确保使用上一个循环迭代结束时的值重新进行赋值。这一性质在闭包中会有所体现。

for (let i=1; i<=5; i++) { 
  setTimeout( function timer() {
    console.log( i );
  }, i*1000 );
}

每次迭代都会重新声明i,并用上一次迭代结束时i的值来初始化。

提升

提升这里有三点需要注意:

  1. 重复的声明会被忽略
    foo()
    var foo
    function foo() {
    // ...
    }

    函数foo声明提升,变量foo声明会被忽略

  2. 函数声明会提升,但是函数表达式不会提升(包括具名的函数表达式)
  3. 函数会首先被提升,然后才是变量