es6块级绑定笔记

142 阅读3分钟

作用域

作用域:编程语言最基本的功能就是存储和访问变量的值,如何对变量存储/访问的某种良好的规则,就是作用域。作用域负责收集并维护由所有声明的标示符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。

作用域是根据名称查找变量的一套规则。当一个块或者函数嵌套在另外一个块或者函数中时,就发生了作用域嵌套。

词法作用域:定义在词法阶段的作用域。词法作用域是你在写代码时将变量和块作用域写在哪里来决定的,因此词法分析器处理代码时保持作用域不变。

函数作用域:每声明一个函数都会为自身创建一个作用域,属于这个函数的全部变量都可以在这个函数范围内使用/复用。一段代码我们可以在它的外部添加一个包装函数,这样就可以将内部的变量和函数定义隐藏(这种方法可以有效解决变量或者函数污染外部作用域,闭包和函数自调用也是这种方法的延伸)。外部作用域无法访问包装函数内部的任何内容。

声明提升

es5及之前只有函数作用域和全局作用域同时也只有两种变量声明,var 和function。 使用函数及变量的声明都将被提升到当前作用域的最顶部。

1.变量提升(var的起作用,只有声明提升,初始化不会):
var a =3;
function b( ) {
    //实际上var了的变量提升到了函数内部的顶部
    console.log( a );
    var a=4;			
}
b( ); // undefind
实际执行
var a =3;
function b( ) {
    var a ; //var a 声明!提升到此,并值为undefined
    console.log( a );
    a=4; // 初始化			
}
b();
2.函数提升(函数声明起作用):
函数提升是把整个函数都提到前面去。 
function f( ) { 
    console.log('I am outside!'); 
}
( function ( ) {		
    if ( false ) {
        // 重复声明一次函数f
        function f( ) {
            console.log( 'I am inside!' );
        }
    }
    f( );
}( ) );//输出'I am inside!'
实际执行:
function f( ) { console.log( 'I am outside!' ); }
( function ( ) {	
    function f( ) { console.log( 'I am inside!' );	}
    if ( false ) {
    // 重复声明一次函数f
    }
    f( );
}( ) );
3.全局作用域的会被后面提升上来的覆盖( var的变量为undefined ), 局部作用域的会提升到函数内部的顶部;变量只有var的会提升,函数只有函数声明会提升;
4:函数声明和函数表达式
function a( ){ } //函数声明  会提升
所以 :
a( );
function a ( ){ }  //正确
var b = function ( ) { } //函数表达式 不会提升
所以:
b( );
var b = function ( ) { } //错误

块级声明

es6引入了块级作用域,并新增了四种声明let/const/import/class。

 
1.// 只在当前作用域内可以访问
{
    let a = 10;
    var b = 1;
}
b // 1
a // ReferenceError: a is not defined.

2.// 同一作用域里不允许重复声明

let a = 'aaa';
let a = 'bbb'; //报错 :语法错误

let a = 'aaa';
{let a = 'bbb';} // 不会报错

3.// 不会变量提升

console.log(a); // 报错
let a; 

4.//暂时性死区 TDZ
var a =1;
{
	let a = 3;
}
// 报错 :引用错误

5.//全局声明不会赋值到window对象

window.d = 123
let d = 234
console.log(d); // 234


2.let/const/import/class也遵守上述规则。
3.const是常量,不可再次被赋值(只限于栈内存里数据,栈内存放的基本数据类型和引用类型的地址不可变)

循环中使用

1.let
for(let i =0; i<10; i++){
 let i = 123;
 setTimeout(
	()=>{console.log(i);},
 1000);
}
// 30786
// 123
console.log(i) // ReferenceError: i is not defined

for(var i =0; i<10; i++){
 setTimeout(
	()=>  {console.log(i);},
  1000);
}
// 51
// 10

for(let i =0; i<10; i++){
 setTimeout(
	()=>  {console.log(i);},
  1000);
}
// 0 1 2 3 4 5 6 7 8 9

2.const
const 在for循环中循环一次后会报错,因为i++会修改值;
在for infor of中则可以正常使用,因为每次循环会创建一个常量。

// 51
// 10