ES6--声明与表达式(let与const、解构赋值)

目录

声明与表达式

1、let与const

(1)let命令

(2)const命令

(3)注意要点

2、解构赋值

(1)概述

(2)解构模型

(3)数组模型的结构(Array)

(4)对象模型的结构(Object)


2039年  

h5制定

修饰自定义的标识符:  let  const  var  function

笔试题——var let const 

var let const 的相同点:

    三者都可以声明变量

var let const 的区别:

1.变量提升

var声明的变量存在变量提升,即变量可以在声明之前调用,值为undefined

let和const不存在变量提升,即它们所声明的变量一定要在声明后使用,否则报错

2.块级作用域

var不存在块级作用域

let和const存在块级作用域

3.重复声明

var允许重复声明变量

let和const在同一作用域不允许重复声明变量

4.修改声明的变量

var和let可以

const声明一个只读的常量。一旦声明,常量的值就不能改变,但对于对象和数据这种引用类型,内存地址不能修改,可以修改里面的值。
 

声明与表达式

1、let与const

ES6新增加了两个重要的 JavaScript 关键字: letconst

  • let 声明的变量只在 let 命令所在的代码块内有效(块级作用域、局部作用),ES6 推荐在函数中使用 let 定义变量,而非 var。

  • const 声明一个只读的常量,一旦声明,常量的值就不能改变。

(1)let命令

  • 基本用法

//{}括起来的代码块
{
  let a = 0;
  console.log(a);   // 0
}
console.log(a);   // 报错 ReferenceError: a is not defined

  • 代码块内有效

(es5代码块没有作用域)    ES6中代码块中let有作用域     不同作用域去取变量会报错

{
    let a = 0;
    var b = 1;
    
}
console.log(b); // 1
console.log(a); // ReferenceError: a is not defined    报错

  • 不能重复声明

同一个作用域内,定义重复变量,会报错:a已经被定义了

let不可以重复声明,但是可以重复赋值。

var a = 1;
var a = 2;
console.log(a);  // 2
​
let b = 3;
let b = 4;
console.log(b);  // Identifier 'a' has already been declared  报错:a已经被定义了

var i=1
let i=1
console.log(i)  //Uncaught SyntaxError: Identifier 'i' has already been declared

for循环计数器很适合用let

for (var i = 0; i < 10; i++) {
  setTimeout(function(){
    console.log(i);
  })
}
// 输出十个 10
​
for (let j = 0; j < 10; j++) {
  setTimeout(function(){
    console.log(j);
  })
}
// 输出 0~9

变量 i 是用 var 声明的,在全局范围内有效,所以全局中只有一个变量 i, 每次循环时,setTimeout 定时器里面的 i 指的是全局变量 i ,而循环里的十个 setTimeout 是在循环结束后才执行,所以此时的 i 都是 10。

变量 j 是用 let 声明的,当前的 j 只在本轮循环中有效,每次循环的 j 其实都是一个新的变量,所以 setTimeout 定时器里面的 j 其实是不同的变量,即最后输出0~9。(若每次循环的变量 j 都是重新声明的,如何知道前一个循环的值?这是因为 JavaScript 引擎内部会记住前一个循环的值)。

  • 不存在变量提升

console.log(a);  //undefined
var a = "banana";
​
console.log(b);  //ReferenceError: b is not defined
let b = "apple";

变量 a 用 var 声明存在变量提升,所以当脚本开始运行的时候,a 已经存在了,但是还没有赋值,所以会输出 undefined。

变量 b 用 let 声明不存在变量提升,在声明变量 b 之前,b 不存在,所以会报错。

(2)const命令

与let不同: 不能重新赋值

 const a=1;          a=100;    会报错,不能重新赋值

const 声明一个只读变量,声明之后不允许改变。意味着,一旦声明必须初始化,否则会报错。

const a;   会报错: 没有初始化

(初始化:第一次赋值,var b只是声明,没有赋值,所以要 b = 2才是初始化)

        //对象是引用数据,没有改变存储空间就可以
        const obj = {
            name:"karen"
        }
        obj.age=20
        console.log(obj)   //{name: 'karen', age: 20}
  • 基本用法

const PI = "3.1415926";
console.log(PI);  // 3.1415926
​
const MY_AGE;  // SyntaxError: Missing initializer in const declaration    
  • 暂时性死区

        var PI = "a";
        if (true) {
            console.log(PI); // ReferenceError: PI is not defined
            const PI = "3.1415926";
        }   //因为里面有const,就把大括号看成一个函数了,让其有作用域了,就没有去外面找PI

ES6 明确规定,代码块内如果存在 let 或者 const,代码块会对这些命令声明的变量从块的开始就形成一个封闭作用域。代码块内,在声明变量 PI 之前使用它会报错。

(3)注意要点

  • let 和const 关键词声明的变量不具备变量提升(hoisting)特性

  • let 和 const 声明只在最靠近的一个块中(花括号内)有效

  • 当使用常量 const 声明时,请使用大写变量(也不是必须),如:CAPITAL_CASING

  • const 在声明时必须被赋值

  • const 如何做到变量在声明初始化之后不允许改变的?使用 const 声明复杂类型对象时要慎重。

{
  const ARR = [5,6];
  ARR.push(7);
  console.log(ARR); // [5,6,7]
  ARR = 10; // TypeError
}

严格模式下函数不会隐式提升,变量会提升==>  所以  尽量不在if里面声明变量函数,但是可以用let

//非严格模式下: 
    <script>
        console.log(a)  //und
        console.log(fn)   //und
        if(true) {    //这里改为false,上面还是两个und
            var a=100
            function fn(){}
        }
    </script>
 <script>
        //严格模式下,在每个脚本的开头写
        "use strict"
        console.log(a)  //und
        console.log(fn)   //报错 Uncaught ReferenceError: fn is not defined
        if(false) {   //写true  上面结果还是一样的
            var a=100
            function fn(){}
        }
</script>

笔试题——let、提前声明、if、赋值

//脚本运行初  在全局作用域先扫描关键字var a;
			//1
			console.log(a)   //und
			if(false) {   //写true也为und     无论if成立与否,下面的var a是要提升的,false的话就是下面a不赋值
				var a=0
			}
			//2
			console.log(a);  //und
			console.log(b);   //报错  Uncaught ReferenceError: b is not defined
			if(true){
				var a=0;   
				let b=0;
			}
			//3
			if(true){
				var a=0;
				let b=0;
			}
			console.log(a);  //0
			console.log(b);  //报错 Uncaught ReferenceError: b is not defined
			

2、解构赋值

(1)概述

  • 解构赋值是对赋值运算符的扩展。

  • 是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。

  • 在代码书写上简洁且易读,语义更加清晰明了;也方便了复杂对象中数据字段获取。

  • 声明标识符,按照某种数据模型 解析并赋值给声明的标识符(变量)

  • 解构有默认值

(2)解构模型

在解构中,有下面两部分参与:

  • 解构的源,解构赋值表达式的右边部分。

  • 解构的目标,解构赋值表达式的左边部分。

(3)数组模型的结构(Array)

  • 基本

let [a, b, c] = [1, 2, 3];
console.log(a, b, c); //1 2 3
  • 可嵌套

let [a, [[b], c]] = [1, [[2], 3]];
console.log(a, b, c); //1 2 3
  • 可忽略

let [a, , b] = [1, 2, 3];
console.log(a, b); //1 3
  • 不完全解构

let [a = 1, b] = []; // a = 1, b = undefined
  • 剩余运算符

let [a, ...b] = [1, 2, 3];
console.log(a, b); //a = 1, b = [2,3]
  • 字符串

在数组的解构中,解构的目标若为可遍历对象,皆可进行解构赋值。可遍历对象即实现 Iterator 接口的数据。

let [a, b, c, d, e] = 'hello';
console.log(a, b, c, d, e); //h e l l o

  • 解构默认值

let [a = 2] = [undefined]; // a = 2

当解构模式有匹配结果,且匹配结果是 undefined 时,会触发默认值作为返回结果。

let [a = 3, b = a] = [];     // a = 3, b = 3
let [a = 3, b = a] = [1];    // a = 1, b = 1
let [a = 3, b = a] = [1, 2]; // a = 1, b = 2

1. a 与 b 匹配结果为 undefined ,触发默认值:a = 3; b = a =3

2. a 正常解构赋值,匹配结果:a = 1,b 匹配结果 undefined ,触发默认值:b = a =1

3. a 与 b 正常解构赋值,匹配结果:a = 1,b = 2

笔试题:

        function fn(fm = function fg(a) {
            console.log(a, b)  //Uncaught ReferenceError: b is not defined
        }) {
            // console.log(a)
            var b = 100
            fm()
        }
        fn()

(4)对象模型的结构(Object)

  • 基本

let { foo, bar } = { bar: 'bbb' , foo: 'aaa'};
// foo = 'aaa'
// bar = 'bbb'
 
let { baz : foo } = { baz : 'ddd' };
// foo = 'ddd'
  • 可嵌套可忽略

let obj = {p: ['hello', {y: 'world'}] };
let {p: [x, { y }] } = obj;
// x = 'hello'
// y = 'world'
let obj = {p: ['hello', {y: 'world'}] };
let {p: [x, {  }] } = obj;
// x = 'hello'
  • 不完全解构

let obj = {p: [{y: 'world'}] };
let {p: [{ y }, x ] } = obj;
// x = undefined
// y = 'world'
  • 剩余运算符

let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40};
// a = 10
// b = 20
// rest = {c: 30, d: 40}
  • 解构默认值

let {a = 10, b = 5} = {a: 3};
// a = 3; b = 5;
let {a: aa = 10, b: bb = 5} = {a: 3};
// aa = 3; bb = 5;

        var obj={age:200,name:"karen"}
        var {age,name}=obj
        //隐式代码
        // var age=obj.age
        // var name=obj.name
        console.log(age)  //200

        var arr=[100,200]
        var [a,b]=arr
        //var a=arr[0]
        //arr b=arr[1]

        //如果报错:什么属性,函数有问题,真正的问题是调用的问题
        var {x1:{x2},x3}=obj3
        // var x1=obj3.x1
        // var x2=obj3.x1.x2  //报错    因为obj.x1是undef,然后用undef.x2就会报错
        // var x3=obj3.x3
        function fn({x,y}) {
            //{x,y}=obj
        console.log(x)
        console.log(x)
        }
        var obj={x:100,y:200}
        fn(obj)

        let [a,{son:[{age,s2:{son:[x1,y1]}}]}]=obj
        // let y1=obj[1].son[0].s2.son[1]

        let [pwd,setpwd] =fn()
        setpwd(pwd)
        //根据这两行代码就知道:fn()返回值是数组,arr[1]是一个函数,就可以设计为:
        function fn(){
            return [1,function(arg){}]
        }

var arr=[1,2,3,5]
var {a,b,length}=arr
console.log(length)  //4

let arr[0].age=90;  //错误,因为这是赋值,赋值应该写在右边
let [{age}]=80;   //这个是可以的



	        let obj={a:20}
			let {a=10}=obj
			//隐式操作:let a=10;  a=obj.a; 
			console.log(a)  //20


			let obj={}
			let {a=10}=obj
			//隐式操作:let a=10;  a=obj.a; 
			console.log(a)   //10
			
			// undefined是ES6的一个bug
			// let obj={a:undefined}
			// let obj={a:0}
			let obj={a:null}
			let {a=10}=obj  //这个是默认值。下面会先取自己的值,然后取默认值
			//隐式操作:let a=10;  a=obj.a; 
			console.log(a)  //10  0  null

重点:

			let arr1=[x=100,y=200]
			//解析声明变量名字叫arr1  值是数组(初始化) 数组第一个值是一个赋值表达式:表达100  同理:200
			let [a=10,b=20]=arr1
			//声明了两个变量:let a=10,let b=20  
			//然后执行解构: 
			//if(arr1[0]!=undefined){a=arr1[0]};
			//if(arr1[0=1]!=undefined){b=arr1[1]}
			console.log(a,b,x,y)  //100  200  100  200

解构赋值只会声明最小层的变量,外面的不会声明,去打印外层会报错

			//s1是里面的,所以let声明的是s1,sons没有声明,所以报错
			let obj={name:"karen",age:22,sons:[{name:"jack",age:1}]}
			let {name,sons:[s1]}=obj
			console.log(name)    //karen
			console.log(s1)    //{name: 'jack', age: 1}
			console.log(sons)   //Uncaught ReferenceError: sons is not defined

 let不能修饰两个相同的变量,所以报错


			let obj={name:"karen",age:22,sons:[{name:"jack",age:1}]}
			let {name,sons:[{age,name}]}=obj
			console.log(age)  //Uncaught SyntaxError: Identifier 'name' has already been declared
			console.log(name) 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值