美文网首页
ES6(一)块级绑定

ES6(一)块级绑定

作者: 蒋小花_4b6c | 来源:发表于2020-04-15 19:01 被阅读0次

JS中使用变量绑定数据,统一个变量不同的声明方式输出不同的值,那末我们一起来看看吧,Let's go!

 1.块级绑定

 var let const

首先解释一个概念:

变量提升Hosting:无论其实际声明位置在何处,都会被视为声明于所在函数的顶部,如果声明不在任意函数内,则视为在全局作用域的顶部。

初学需要花点儿时间来习惯变量提升,如果不理解这种思想可能会导致bug

因此引入块级作用域,让变量的生命周期更可控。

咱们来做道题测试测试吧

() => {

    var a = 0;

    if(true) {

        a = 1;

        function a() {};

        a = 21;

        console.log('in', a);

    }

    console.log('out', a);

}

正确答案是: in 21, out 1

详细讲解请看这里: https://mp.weixin.qq.com/s/UNYO-OsIul8_gUdcghIBwQ

块级作用域

 让所声明的变量在指定块的作用域外无法被访问。块级作用域(又被称为词 法作用域)在如下情况被创建:

    1.  在一个函数内部

    2.  在一个代码块(由一对花括号包裹)内部

let

基本可以代替var,作用域在当前的代码块中

一对{}里面使用let声明变量,下面行的代码就可以使用此变量了

如果需要整个{}内都可以使用A变量,则需要把A变量放到{}顶部

function getValue(condition) {

    if(condition) {

        let value = 'blue';

        console.log(value); // return value;

    } else {

        console.log(value);

        return null;

    }

    console.log(value);

}

在这个例子中value 只在if{}里面才生效,其他地方没有value

TIPS: 

1.禁止重复声明同一变量

() => {

    var value = 1;

    let value = 2; // 错误

}

function change(condition) {

    var value = 1;

    if(condition) {

        let value = 2;

        console.log(value); // return  value;

    } else {

        return null;

    }

    console.log(value);

}

const 常量

const用来声明常量constant,常量初始化之后不能被改变,且必须在声明时就初始化。

const maxItems = 30;

const minItems; // 语法错误未初始化

let const 都是块级声明,语句块外部无法访问,变量也不会提升。

if (condition) {

    const maxItems = 5;

    // 其他代码

    }

    // maxItems 在此处无法访问

常量 maxItems 在 if 语句内被声明,在if{}外部无法被访问

var message = "Hello!";   let age = 25;

// 二者均会抛出错误

const message = "Goodbye!";    const age = 30;

变量已经被声明就不得用const再次声明。

const maxItems = 5;

maxItems = 6;      // 抛出错误

const声明的常量不得再次赋值。

  const 声明会阻止对于变量绑定与变量自身值的修改,这意味着 const 声明并不会阻止对 变量成员的修改。

const person = {name: "Nicholas"

};

// 工作正常

person.name = "Greg";

// 抛出错误

person = {

name: "Greg"

};

不能修改常量本身的值,但可以修改常量对象的属性值。

补充一个概念:‘暂时性死区’

if (condition) {

    console.log(typeof value);  // 引用错误

let value = "blue";

}

此处的 value 变量使用了 let 进行定义与初始化,但该语句永远不会被执行,

因为声明之 前的那行代码抛出了一个错误。

出现该问题是因为:value  位于暂时性死区

temporal dead zone , TDZ )内。

该名称并未在 ECMAScript 规范中被明确命 名,但经常被用于描述 let 或 const 声明的变量为何在声明处之前无法被访问。

console.log(typeof value); // "undefined"

if (condition) {

    let value = "blue";

}

当 typeof 运算符被使用时, value 并没有在暂时性死区内,因为这发生在定义 value 变 量的代码块外部。这意味着此时并没有绑定 value  变量,而 typeof 仅单纯返回了

  "undefined" 。

for (var i = 0; i < 10; i++) {

    process(items[i]);

}

// i 在此处仍然可被访问

console.log(i);

for (let i = 0; i < 10; i++){process(items[i]);

}

// i 在此处不可访问,抛出错误

console.log(i);

变量 i  仅在 for  循环内部可用,一旦循环结束,该变量在任意位置都不可访问。

 

IIFE

var funcs = [];

for (var i = 0; i < 10; i++) {

funcs.push(function() { console.log(i); });

}

funcs.forEach(function(func) {func(); // 输出数值 "10" 十次

});

你原本可能预期这段代码会输出 0 到 9 的数值,但它却在同一行将数值 10 输出了十次。这是 因为变量 i 在循环的每次迭代中都被共享了,意味着循环内创建的那些函数都拥有对于同一 变量的引用。在循环结束后,变量 i 的值会是 10 ,因此当 console.log(i) 被调用时, 每次都打印出10 。

为了修正这个问题,开发者在循环内使用立即调用函数表达式(IIFEs),以便在每次迭代中 强制创建变量的一个新副本,示例如下:

var funcs = [];

for (var i = 0; i < 10; i++) {

 funcs.push((function(value) {

    return function() {

    console.log(value);

}

}(i)));

}

funcs.forEach(function(func) {func(); // 从 0 到 9 依次输出

});

这种写法在循环内使用了 IIFE 。变量 i 被传递给 IIFE ,从而创建了value 变量作为自身 副本并将值存储于其中。 value 变量的值被迭代中的函数所使用,因此在循环从 0 到9 的过 程中调用每个函数都返回了预期的值。幸运的是,使用 let 与 const 的块级绑定可以在 ES6 中为你简化这个循环。

在循环内使用let声明

var funcs = [];

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

console.log(i);

});

}

funcs.forEach(function(func) {func(); // 从 0 到 9 依次输出

}

在for-in中使用

var funcs = [],object = {

a: true,b: true,c: true

};

for (let key in object) {funcs.push(function() {

console.log(key);

});

}

funcs.forEach(function(func) {

func();     // 依次输出 "a"、"b"、 "c"

});

但是注意不要使用const来声明:

function getConst3() {

    var arr = [];

    for(const i = 0; i < 10; i++) {

        arr.push(function() {

            console.log(i);

        });

    }

    arr.forEach(item => {

        item();

    });

}

但是可以在for-in和for-of中使用const:

for (const key in object) {funcs.push(function() {

    console.log(key);

});

}

是因为,循环未每次迭 代创建了一个新的变量绑定,而不是试图去修改已绑定的变量的值

使用var定义变量时变量时全局变量,可以通过window.变量来访问(变成window的一个属性 这是js的工作方式),那这就意味着var可能会重写其他的变量。

使用let、const虽然会在全局创建新的绑定,但是不会覆盖全局对象的值,也不会有任何属性背添加到全局对象上。

可以用以下代码测试看看:

const RegExp = 'hi';

console.log(RegExp, window.RegExp, RegExp === window.RegExp);

var newWord = 'word';

console.log(‘ newWord ’ in window, window.newWord);

总结:

1.可以尽量使用let代替var(默认情况下使用let),常量使用const。

或者

默认情况下使用const,当变量需要被修改的时候才用let。‘其理论依据是大部分 变量在初始化之后都不应当被修改,因为预期外的改动是 bug 的源头之一’

2.let 与 const不会进行提升,并且 只会在声明它们的代码块内部存在。

不能在变量声明位置之前访问 它们,即便使用的是typeof 这样的安全运算符

3.块级绑定当前的最佳实践就是:在默认情况下使用 const ,而只在你知道变量值需要被更改 的情况下才使用 let 。

相关文章

  • Understanding ES6 -- 深入理解ES6书籍

    understanding es6 -- Nicholas C. Zakas 块级绑定 function ...

  • es6新特性

    ES6 新特性 ES6 新特性 一ES6简介 二块级作用域绑定1 let声明2 const声明Constant D...

  • ES6(一)块级绑定

    JS中使用变量绑定数据,统一个变量不同的声明方式输出不同的值,那末我们一起来看看吧,Let's go! 1.块级绑...

  • ES6 块级绑定

    var 声明与变量提升 使用 var 关键字声明的变量,无论其实际声明位置在何处,都会被视为声明于所在函数的顶部,...

  • [ES6] 块级绑定

    使用var声明变量 全局变量挂载到全局对象:全局对象成员污染问题 允许重复的变量声明:导致数据被覆盖 变量提升:怪...

  • 《深入理解ES6》学习笔记(第三天)

    《深入理解ES6》学习笔记(第三天) 第一章 块级作用域绑定 第2节 块级声明块级声明用于声明在指定块的作用域之外...

  • 《深入理解ES6》学习笔记(第四天)

    《深入理解ES6》学习笔记(第四天)第一章 块级作用域绑定 第2节 块级声明 2.1 cont声明 使用const...

  • es6-块级作用域绑定

    title: es6-块级作用域绑定date: 2018-01-24 21:32:33tags: es6 前言 花...

  • 一、块级绑定

    ES2015 一、块级绑定 1、let、const和块级作用域 var 变量提升(hoisting )   使用v...

  • ES6 学习心得 --- 块级绑定

    块级绑定:变量在块级作用域中的声明绑定形式。 块级绑定新的最佳实践 总结:默认情况下使用 const 、并且只在...

网友评论

      本文标题:ES6(一)块级绑定

      本文链接:https://www.haomeiwen.com/subject/kfxxvhtx.html