angular从入门到一脸懵逼

Lesson2:ES6简易入门(let、const关键字,结构赋

2017-09-11  本文已影响21人  天魂_TH

1. let关键字

let的用途:

在之前写js时候,用var来声明一个变量,es6里面除了var还有其他的声明变量的关键字,let就是其中之一,那么let的用途就是用来声明变量的。

let与var

既然都是声明变量的关键字,那肯定就有区别,要不就不会有第二个了,看看有什么区别。

使用 var 的不足之处:
1.var声明的变量作用于函数内,let声明的变量作用与块级作用域。

任何一对“大括号{ }”中的语句都属于一个块,在大括号里面用let定义的所有变量在大括号外是不可见的,我们称之为块级作用域。

2.用var声明变量的时候会导致“变量提升”。
JavaScript的函数定义有个特点,它会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部:

'use strict';

function foo() {
    var x = 'Hello, ' + y;
    alert(x);
    var y = 'Bob';
}

foo();

虽然是strict模式,但语句var x = 'Hello, ' + y;并不报错,原因是变量y在稍后申明了。但是alert显示Hello, undefined,说明变量y的值为undefined。这正是因为JavaScript引擎自动提升了变量y的声明,但不会提升变量y的赋值。

对于上述foo()函数,JavaScript引擎看到的代码相当于:

function foo() {
    var y; // 提升变量y的申明
    var x = 'Hello, ' + y;
    alert(x);
    y = 'Bob';
}

如果用let重写foo()

'use strict';

function foo() {
    var x = 'Hello, ' + y;
    alert(x);
    let y = 'Bob';
}

foo(); //结果:报错 y is not defined

用let关键字来定义y;这样y在代码块内就不会提升了。报错是因为用let声明的变量要先声明再使用,上面代码里未声明定义就使用,就只有报错了。

使用let的注意点:

注意1:同一个块级作用域内,不允许重复声明同一个变量。

// 错误示范一:
{
  var a =1;
  let a =2;  //报错,因为a已经用var声明过
}
// 错误示范二:
{
  let a =1;
  let a= 2; //还是报错,a已经用let声明过。
}

注意2:函数内不能用let重新声明函数的参数

// 错误示范:
function say(word){
   let word = 'hello Jack';  //报错:用let重新声明word参数
   alert(word)
}
say('hello Lili'); 
// 函数内用let重新声明word这个参数,会报错的,千万别这么干。

2. const关键字

const 的作用

const是constant(常量)的缩写,const和let一样,也是用来声明变量的,但是const是专门用于声明一个常量的,顾名思义,常量的值是不可改变的。

常量的特点:

1、不可修改

    const Name = '张三';
    Name = '李四'; // 错误,企图修改常量Name

2、只在块级作用域起作用,这点与let关键字一样。

    if(1){
       const Name = '张三';
    }
    alert(Name); //错误,在代码块{ }外,Name失效

3、不存在变量提升,必须先声明后使用,这点也跟let关键字一样。

    if(1){
        alert(Name);//错误,使用前未声明
        const Name = '张三';
    }

4、不可重复声明同一个变量,这点跟let也一样。

    var Name  = '张三';
    const  Name = '李四';//错误,声明一个已经存在的变量Name

5、声明后必须要赋值

    const NAME; //错误,只声明不赋值

使用const的注意点:

    const Person = {"name":"张三"};
    Person.name = "李四";
    Person.age = 20;
    console.log(Person);
    //结果:正常输出{name: "李四", age: 20}

如上常量是一个对象,常量是可以修改的,为什么呢?
这里用到了传址赋值,什么叫传址赋值?

传址:在赋值过程中,变量实际上存储的是数据的地址(对数据的引用),而不是原始数据或者数据的拷贝。

用const来声明一个对象类型的常量,就是传址赋值。而不可修改的是对象在内存中的地址,而不是对象本身。
所以,这就很好的解释刚刚的这段代码为什么不会报错,而是正常输出了。
上面代码中修改的只是Person本身,修改的是name属性和增加一个属性age,而地址没变,也不可变,所以并没有违背常量不可修改的约定。

但是,如果这样写呢,就会报错:

    const Person = {"name":"张三"};
    Person.age = 20;
    Person = {}; 
    //错误,企图给常量Person赋新值(新地址)
9.12更新

3. 解构赋值

官方的解释:

ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。

上一段代码进一步解释一下什么叫解构赋值:

    var arr = [1,2,3]; // 把数组的值分别赋给下面的变量;
    var a = arr[0];
    var b = arr[1];
    var c = arr[2];

    console.log(a); // a的值为1
    console.log(b); // b的值为2
    console.log(c); // c的值为3

以上是传统的变量赋值,将数组的元素值1,2,3分别赋值给变量a,b,c,结果也是如我们所愿,赋值成功。

    var [a,b,c] = [1,2,3]; //把数组的值分别赋给下面的变量;
    console.log(a); // a的值为1
    console.log(b); // b的值为2
    console.log(c); // c的值为3

以上是变量的解构赋值,赋值的代码减少了,只需要将变量a,b,c作为一个数组的元素,然后将数组[1,2,3]赋值给数组[a,b,c]即可,变量a,b,c即可分别得到对应的值,这种叫做数组的解构赋值。

数组的解构赋值注意点:

1、结构赋值可以嵌套的

    var [ a,b,[ c1,c2 ] ] = [ 1,2,[ 3.1,3.2 ] ];
    console.log(c1); // 结果:c1的值为3.1
    console.log(c2); // 结果:c2的值为3.2

2、不完全解构

    var [a,b,c] = [1,2];
    console.log(a); // 结果:a的值为1
    console.log(b); // 结果:b的值为2
  1. 赋值不成功,变量的值为undefined
    var [a,b,c] = [1,2];
    console.log(a); // 结果:a的值为1
    console.log(b); // 结果:b的值为2
    console.log(c); // 结果:c的值为undefined
  1. 允许设定默认值
    var [a,b,c=3] = [1,2];
    console.log(a); // 结果:a的值为1
    console.log(b); // 结果:b的值为2
    console.log(c); // 结果:c的值为3
  1. 重新赋值会覆盖默认值
    var [a,b,c=3] =[1,2,4];
    console.log(a); // 结果:a的值为1
    console.log(b); // 结果:b的值为2
    console.log(c); // 结果:c的值为4

⚠️ 注意:当新的值为undefined的时候,是不会覆盖默认值的。

对象的解构赋值

对象的解构赋值跟数组的解构赋值很类似,上代码:

    var {a, b, c} = {a: 1, b: 2, c: 3};
    console.log(a); // 结果:a的值为1    
    console.log(b); // 结果:b的值为2
    console.log(c); // 结果:c的值为3

对象的解构赋值不会受到属性的排列次序影响(数组则会受影响),它是跟属性名关联起来的,变量名要和属性名一致,才会成功赋值。

    var { a, b, c } = {a: 1,  c: 3, b: 2};
    console.log(a); // 结果:a的值为1
    console.log(b); // 结果:b的值为2
    console.log(c); // 结果:c的值为3

如果变量找不到与其名字相同的属性,就会赋值不成功:

    var { a } = {"b":2};
    console.log(a); // 结果:a的值为undefined

💡 变量名与属性名不一样的变量解构赋值:

    var { b: a} = {b: 2};
    console.log(a); // 结果:a的值为2

对象的结构赋值注意点:

1、对象解构赋值可以嵌套

    var {a: {b}} = {a: {b: 1}};
    console.log(b); // 结果:b的值为1

2、可以指定默认值

    var {a, b=2} = {a: 1};
    console.log(b); // 结果:b的值为默认值2

字符串的解构赋值

除了对象和数组可以解构赋值外,字符串也可以结构赋值,上代码:

    var [a, b, c, d, e, f] = "热忱一直在!";
    console.log(a); // 热
    console.log(b); // 忱
    console.log(c); // 一
    console.log(d); // 直
    console.log(e); // 在
    console.log(f); // !

解构赋值的用途

一、交换变量的值

    var x = 1;
    var y = 2;
    [x, y] = [y, x];

简单的一行代码即可成功交换x,y的值。

二、提取函数返回的多个值
函数只能返回一个值,我们可以将多个值装在一个数组或者对象中,再用解构赋值获取其中的值。

    function foo(){
        return {name: "neo",  age: 31}
    }
    var {name, age} = foo();
    console.log(name); // 结果:neo
    console.log(age); // 结果:31

将foo()的返回值直接通过结构赋值赋给变量name和age,实现快速的提取对应的值。

三、定义函数参数

    function foo({name,  age}){
        console.log(`姓名:${name}`);
        console.log(`年龄:${age}`);
    }
    foo({name:  "neo",  age: "31",  sex: "male"});

通过这种写法, 很方便就能获取JSON对象中想要的参数,例如案例中,只需要获取实参中的:name,age而不需要管其他的参数。

上一篇下一篇

猜你喜欢

热点阅读