【Js01】变量以及es6的块级做用域

1.Js的变量特色

1.1变量声明的提高

先看一道面试题es6

console.log(v1);
var v1 = 100;
function foo() {
    console.log(v1);
    var v1 = 200;
    console.log(v1);
}
foo();
console.log(v1);

var声明变量时会提高到它所在做用域的顶端去执行,到咱们代码所在的位置来赋值。面试

1.2函数的提高

函数的两种声明:浏览器

//函数声明式
function bar () {}
//函数字面量式 , 合普通变量提高的机制同样
var foo = function () {}

函数声明式的提高现象和变量提高略有不一样:函数

console.log(bar);
function bar () {
  console.log(1);
}
//打印结果:ƒ bar () {
//  console.log(1);
//}

函数提高是整个代码块提高到它所在的做用域的最开始执行,上述代码执行顺序至关于.net

function bar () {
  console.log(1);
}
console.log(bar);
思考下面的代码,这就是函数优先规则。
foo(); //3
 
var foo;
 
function foo () {
    console.log(1);
}

function foo () {
    console.log(3);
}
 
foo = function () {
    console.log(2);
}

下面这段代码,在低版本的浏览器中,函数提高不会被条件判断所控制,输出2;可是在高版本的浏览器中会报错,因此应该尽量避免在块内部声明函数code

foo(); //低版本:2  //高版本: Uncaught TypeError: foo is not a function
 
var a = true;
 
if(a){
    function foo () { console.log(1); }
}else{
    function foo () { console.log(2); }
}

2.ES6的块级做用域绑定

2.1 let声明

  • let声明不会被提高
  • 禁止同一做用域的重复声明
  • 块级做用域内有效

2.2 const 声明

  • 声明的值是常量,一旦被设定后不可更改和从新赋值。
  • 必须初始化。
  • 块级做用域内有效

用const声明对象对象

const person = {
    name: 'changchang'
}
//能够修改对象属性的值
person.name = 'zhangchangchang';

//抛出语法错误
person = {name: 'es6'}

2.3 循环中的块做用域绑定

for (let i = 0; i < 10; i++){
    process(items[i]);
}
// i在这里不可访问,抛出错误
console.log(i);

2.4 循环中的函数

var funcs = [];

for (var i = 0; i < 10; i++){
    funcs.push(function() {
        console.log(i);
    })
}

funcs.forEach((ele)=>{
    ele(); //输出10次数字10
})

//循环离的每次迭代同时共享着变量i,循环内部建立的函数所有保留了相对变量的引用。循环结束时变量i的值为10,因此forEach时每次都会输出10。
//用forEach来console.log(ele)得出ƒ (){console.log(i)},而此时i=10,因此输出10次10

循环中的当即执行函数(IIFE)blog

var funcs = [];

for (var i = 0; i < 10; i++){
    funcs.push((function(value) {
        return function(){
            console.log(value);
        }
    }(i))); //把当前的i存放到形参value里
}

funcs.forEach((ele)=>{
    ele(); //输出0 1 2...
})

//若是console.log(ele),得出ƒ (){console.log(value);}

循环中的let声明作用域

var funcs = [];

for (let i = 0; i < 10; i++){
    funcs.push(function() {
        console.log(i);
    })
}

funcs.forEach((ele)=>{
    ele(); //输出0 1 2 ...
})

//let在每次迭代循环都会建立一个新变量

对于for-in合for-of也是同样的get

var funcs = [];
var object = {a: true, b:true, c: true};

for (let key in object){
    funcs.push(function(){
        console.log(key);
    });
}

funcs.forEach((ele)=>{
    ele(); //输出a b c ...
})

循环中的const声明

// 报错
for (const i = 0; i < 10; i++){
    ...
}

var object = {a: true, b:true, c: true};
// 能够正常输出,由于每次迭代都会建立一个新绑定
for (const key in object){
    console.log(key);
}

参考文章:
《深刻理解ES6》
https://blog.csdn.net/qq_3971...

相关文章
相关标签/搜索