ES6变量定义与解构

本文详细介绍了ES6中的变量定义,重点讲解了let关键字的特性,包括不存在变量提升、不允许重复声明以及暂时性死区。接着探讨了块级作用域的引入及其必要性。然后,深入解析了变量解构赋值的概念、数组和对象的解构、以及解构赋值的多种应用场景。此外,还讨论了函数扩展,如函数参数的默认值、rest参数和箭头函数的使用,特别是箭头函数中的this指向问题。
摘要由CSDN通过智能技术生成

1.Let关键字

Let是ES6的新增关键字,用来声明变量,它的用法和 var 的用法类似,但是let只在自己所在的代码区域内有效.
  • 例:
//var

var a = [];
	for(var i = 0;i < 10 ;i++){
	       a[i] = function(){
           console.log(i);
       }
}
a[6](); // 结果为10

var 定义的变量遇到for循环的大括号后是不会行程作用域的.所以在上面代码调用时,调用的是一个全局的变量.

//let
var a = [];
	for(let i = 0;i < 10 ;i++){
	       a[i] = function(){
           	console.log(i);
       }
}
a[6](); // 结果为6

以上代码中,i是使用 let 声明的,当前的 i 只在本轮的循环中有效.每一个循环中放入 i 其实都是一个新的变量.所以输出是6

for (let i = 0; i < 3; i++) {
  let i = "abc";
  console.log(i); 
 }
 
//结果:输出3次abc
//原因:在代码块中的变量 i 与 for 循环中的变量 i 不再同一个作用域中;

1.1 let不存在变量提升

var 存在变量提升.即变量在声明之前使用时,值为undefined , js会将声明语句放在所有js代码之前执行则 let则不存在变量提升.

	console.log(a);
	var a = 10;
	//相等于
	var a;
	console.log(a);
	a = 10;
	console.log(a);
	let a = 10;
	
// 提示错误Cannot access 'a' before initialization

1.2不允许重复声明

  • let 不允许在相同的作用域中,重复声明同一个变量
	let a = "hello";
	let a = "world";  
	console.log(a);
	
	//报错: Identifier 'a' has already been declared
	function show(a){
		let a = 10;
	}
	show(100);
	
	//Identifier 'a' has already been declared

以上代码中,函数的参数 a 与函数内部的 a作用域相等,所以会报错。

	function show(a){
        {
            let a = 10;
        }
    }
    show(100);

1.3 暂时性死区

	var tmp = 123;
    if(true){
        tmp = "abc";
        let tmp;
        console.log(tmp);
    }

结果:提示错误 Cannot access 'a' before initialization
使用变量时,会先寻找同一作用域下的变量。以上代码中,tmp=abc会优先寻找到下面的let tmplet tmp不存在变量提升,所以提示错误。
总结:在代码块中,使用 let命令声明变量之前,该变量都是不可用状态,在语法上,称为“暂时性死区”

2.块级作用域

2.1为什么需要块级作用域

ES5 只有全局作用域和局部作用域(函数作用域),没有块级作用域。

  • 缺点1:内部变量可能覆盖外层的变量
	var date = new Date();
	function f(){
	    console.log(date);
	    if(false){
	    	var date = "今天是个好日子"  
	    }
	}
	f();//undefined

上面的案例中,if代码块外部愿意为使用外层的data.但是函数执行后,结果却为undefinend,原因是存在变量的提升,导致内部的data覆盖了外部的date变量。

  • 缺点2:for循环中的计数变量泄露为全局变量
    var hello = "hello"
    
    for (var i = 0; i < hello.length; i++) {
       console.log(hello[i]);
    }
    console.log(i);

以上案例中,for循环中的变量i只是用来作为计数使用,但是for循环执行完成后,它没有消失,而是作为全局变量仍然存在。以后可能不会再使用,造成资源的浪费。

ES6块级作用域

	function show(){
	        let a = "亚索";
	        if(true){
	            let a = "剑豪";
	            {
	                let a = "孤儿索"
	            }
	            console.log(a);
	            
	        }
	        console.log(a);
	    }
	show()

块级作用域下的变量不会对外层的变量造成影响,同时支持多层嵌套。

if(true)let  a = "亚索";
    
console.log(a);

ES6的块级作用域必须有大括号,所以使用if判断时,不可以省略大括号。

3.变量的解构赋值

3.1什么是解构

ES6中,按照一定的模式,从数组或对象中提取值,对变量进行赋值。这个过程叫做解构赋值。

3.2数组解构

const arr = ["诺手","蝎子","劫","EZ","女坦"];
let nuo = arr[0];
let lailai = arr[1];
let jie = arr[2];
let ez = arr[3];
let f = arr[4];
//ES6
let [nuo,lailai,jie,ez,f] = ["诺手","蝎子","劫","EZ","女坦"];

本质上,这种写法属于“模式匹配”。只要赋值号两边的模式相同,左边的变量就会被赋予对应的值。

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

解构失败时,变量的值为undefined。

let [a,b] = [1];
console.log(a);//1
console.log(b);//undefined

不完全解构

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

赋值号两边不是完全相等的。

3.3 对象解构赋值

const obj = {
    name:"亚索",
    skill:"hasakei"
}
let {name,skill} = obj;

变量名与属性名相同,才能取到正确的值。

如果想要自定义变量名,则用:进行修改。

let {name:n,skill} = obj;
console.log(n);

3.4方法解构

var obj = {
    r:function(){
    	console.log("狂风绝息斩");
    },
    e:function(){
    	console.log("e去不复返");
    }
}
const {r,e} = obj;
r();
e();

3.5 注意点

let x;
{x} = {x:1};

以上代码是错误写法。{x}前面如果没有let const的变量声明的关键字,则js会将其视为代码块。

如果需要提前声明变量,则需要将解构语句用小括号包裹起来;。

let x;
({x} = {x:1});

数组本质也是特殊的对象,也可以对数组进行对象属性的解构。

 const arr = ["诺手","蝎子","劫","EZ","女坦"];
 let {length,0:first,4:last} = arr;
 console.log(first);
 console.log(last);

3.6.字符串解构

const str = 'hello';
let [a,b,c,d,e] = 'hello';
let {length} = 'hello';//5

类数组的对象都有一个length属性,我们可以对这个属性进行解构赋值。

3.7 函数参数的解构赋值

function add([x,y]){
	return x+y;
}
let sum = add([1,2]);
console.log(sum);//3

以上案例,函数add的参数表面上一个数组,但是在传入参数的那一刻,数组参数会被解构成变量x和与y.

3.8 用途

交换变量的值

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

从函数中返回多个值

function fn(){
	return [1,2,3];
}
let [a,b,c] = fn();
function fn2(){
    return {
        name:"yasuo",
        age:"25"
    }
}
let {name,age} = fn2();

函数参数的定义

function fn({a,b,c}){
    console.log(a);
    console.log(b);
    console.log(c);
}
fn({c:3,b:2,a:1})

4.函数扩展

4.1 函数参数的默认值

ES6之前,不能为函数的参数设置默认值,只能在代码中进行判断

function show(a,b){
    if(typeof b === "undefined"){
         b = 0;
    }
    console.log(a,b);
}
show(1);

ES6的写法

function show(a,b=0){
	console.log(a,b);
}
show(1);

设置默认值的参数应该在函数的最后面,否则默认值设置是无效的。

 function show(a=0){
 console.log(a,b);
 }
 show(1)//1 undefined

函数的length属性为函数的参数个数。若设置了默认值,length的计数中是不计算设置了默认值的参数的。

4.2 作用域

一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域。

等到初始化结束,这个作用域就会消失。

var a = 1;
function fn(a,b = a){
    console.log(b);
}
fn(2)//2
let a = 1;
function fn(b = a){
    let a = 2;
    console.log(b);
}
fn();//1

函数调用中,(b=a)是一个单独的作用域,a变量不存在,则会去外部寻找。

4.3 rest参数

基本用法

        function add(...v){
            for (var i = 0; i < v.length; i++) {
               console.log(v[i])
            }
            
        }
        add(2,1,3)

rest参数必须是最后一个正式参数。

        //错误写法
        function add(...v,a){
            
        }  

4.4 rest参数和arguments对象的区别

arguments对象不是一个数组,只是一个类似数组的对象。不能使用数组的方法。
rest参数是一个真正的数组,所以可以使用数组得方法

	function sort(...v){
	    // return arguments.sort(); 报错
	    return v.sort()
	}
	console.log(sort(3,1,4,8));

5.箭头函数

5.1定义

箭头函数是对于匿名函数表达式的一种简写方法。

5.2语法

	//普通匿名函数
	var a = function(a,b){
	
	}
	//箭头函数
	//()形参的位置
	//=> 箭头函数的标志
	//{} 函数代码块
	()=>{}
	var fn = function(a,b){
	    console.log(a+b);
	    console.log("我是普通匿名函数");
	}
	fn(10,20);
	var fn2 = (a,b)=>{
	    console.log(a+b);
	    console.log("我是箭头函数");
	}
	fn2(10,20);

5.3其他写法

如果箭头函数只有一个形参,则可以省略小括号。

var fn = a =>{
       console.log(a);
}

如果只包含一个语句,则省略{}return

var fn = a => a*a

箭头函数中没有arguments对象。

var fn = a => {
   console.log(arguments.length);//报错
}

5.4箭头函数中的this指向

箭头函数内部的 this是由上 下文确定的。
他会找到自身定义的位置中的this值,作为自身的this

let div = document.querySelector("div");
    div.onclick = function(){
        console.log(this);//div
    }
    div.onclick = ()=>{console.log(this);}//window
    div.onclick = function(){
         let fn = function(){
             console.log(this);
         }
         fn();//window
        let fn = ()=>{
            console.log(this);
        }
        fn();//div
    }
    let obj = {
        name:"亚索",
        fn:function(){
            console.log(this);
        },
        fun:()=>{
            console.log(this);
        }
    }
    obj.fn();//obj
    obj.fun();//window
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值