天天看點

ES6——let、參數增強、箭頭函數、模闆字元串、for of和解構一、 let二、參數增強三、箭頭函數四、模闆字元串五、for of六、解構

ECMA  ->  ECMAScript  ->  ES
            标準規範
           

ES6: js的第6套标準規範

  • 一、 let
    • 1.1 let特點
    • 1.2 let底層原理
    • 塊級作用域:解決全局污染
    • var let const三個差別
  • 二、參數增強
    • 2.1 參數預設值(default)
    • 2.2 剩餘參數(rest)
    • 2.3 打散數組(spread)...
      • a.複制一個數組:
      • b.合并兩個數組
      • c.淺克隆一個對象
      • d.合并兩個對象
  • 三、箭頭函數
    • 3.1 簡化文法規定
    • 3.2 箭頭函數中的this
      • 圖解
  • 四、模闆字元串
  • 五、for of
      • for of 和 for in 和 forEach()
  • 六、解構
    • 6.1數組解構
    • 6.2 對象解構
    • 6.3 參數解構

一、 let

var

  1. 關鍵字定義的變量可以在使用後聲明,也就是變量可以先使用再聲明。
//var a   		//會将第三行的var a提到最前面,提前聲明變量
console.log(a);	//undefined
var a = 1;		//有var才提升
console.log(a);	//1
           

1.1 let特點

  1. let在全局聲明在window中也找不到
  2. 不允許提前使用let變量,也就是變量需要先聲明再使用,存在塊級作用域。
  3. 同一作用域内不允許重複聲明兩個同名let變量
console.log(a);	//引用報錯ReferenceError:
let a = 1;		//let不再存在提升
console.log(a);	//1
           

1.2 let底層原理

在底層自動轉換為匿名函數自調用,且

變量名

=>

_變量名

示例:

(function(){
    var _a = 100;
 })()
           

塊級作用域:解決全局污染

大括号之間的語句塊就是一個塊級作用域,例如:if、else、while、do-while、for…

在塊級作用域下,let和const聲明的都是局部的,無法被塊級作用域以外通路到。

{//塊級作用域
  var c = 3;
  let d = 4;//局部變量
  const e = 5;//局部常量
}
console.log(e);
           

var let const三個差別

  • var聲明的變量存在提升,在同一個作用域下可以重複聲明同一個變量
  • let聲明的變量不存在提升,在同一個作用域下不允許重複聲明同一個變量,存在塊級作用域,即使在全局作用域下let聲明的變量也不是全局的
  • const 聲明的時候必須指派,不允許重新指派,存在塊級作用域

二、參數增強

2.1 參數預設值(default)

調用函數時,即使不傳入實參值,形參變量也有預設值可用,不至于是undefined

2.定義函數時:

function 函數名(形參1=預設值1, 形參2=預設值2, ...) {
     //調用函數時,給形參傳了實參值,則首選使用者傳入的實參值。
     //如果沒有給形參傳是實參值,則形參預設啟用=右邊的預設值。
}
           

示例:

function fn(a, b, c=0) {
	console.log(a, b, c);
}

fn(10000,2000,500);
//未出現的實參就會使用預設值
fn(10000,2000);//1000,2000,0
fn(10000);//NaN
           

3.舊js版本相容寫法

function 函數名(形參1=預設值1, ...) {
     形參1 === undefined && (形參1=預設值);
}
           

4.預設值隻能解決最後一個形參不确定有沒有的情況!

如果多個形參都不确定有沒有,應該用後邊學的參數解構來解決!

2.2 剩餘參數(rest)

ES6箭頭函數中碰到參數個數不确定的情況,都要用剩餘參數文法來代替arguments(箭頭函數不能使用)

隻要使用arguments,都換成剩餘參數文法!

1.定義函數時

var 函數名=( ...數組名 )=>{
  //将來傳入函數的所有實參值,都會被...收集起來,儲存到...會指定的數組中。
}
           

...

在定義函數時的意思是收集

2.優點:

1). 支援箭頭函數

2). 生成的數組是純正的數組類型,可以使用數組家所有函數

3). 自定義數組名,比arguments簡單

示例一:

//定義一個函數,求任意多個數字的和
var add=(...arr)=>{
    console.log(`本次收到的arr:${arr}`);
    return arr.reduce(
      (捐款箱,目前值)=>捐款箱+目前值, 0
    );
    // return arr.reduce(
    //   function(捐款箱,目前值){
    //     return 捐款箱+目前值
    //   },
    //   0//起始值
    // )
}
console.log(add(1,2,3));//6
console.log(add(1,2,3,4,5));//15
           

3.

...

可以和其它形參配合使用

隻獲得其它形參不要的剩餘參數。

實參值1,實參值2,除實參值1、2之外其餘實參:

...數組名

收集的是除了前兩個形參變量對應的實參值之外的剩餘實參值

示例二

function cal(ename,...arr){
    console.log(ename, arr);
    var total=arr.reduce(
      function(捐款箱,目前值){
        return 捐款箱+目前值
      },
      0//起始值
    );
    console.log(`${ename}的總工資是${total}`)
}
cal("Li Lei",10000,1000,2000);
cal("Han Meimei",3000,500,1000,2000,3000);
           

2.3 打散數組(spread)…

隻要需要多個值,但是多個值是放在數組中給的,将這個數組打散為多個元素值,依次傳給函數的多個形參變量

調用函數時

...

在調用函數時是"打散":将數組打散為多個元素

...

在定義函數時是"收集"

a.複制一個數組:

var arr = [1,2];
var arr2=arr.slice();
           

👇

//先打散數組,将原數組中每個值放入新建立的數組中

b.合并兩個數組

var arr1 = [1,2];
var arr2 = [2,4];
var arr3=[].concat(arr1,arr2)
           

👇

//先将兩個數組打散後,将所有元素都放入新數組中

c.淺克隆一個對象

//先打散obj1對象,然後将打散後的所有屬性,放入新數組中

d.合并兩個對象

👇

//先将obj1和obj2打散後,所有的屬性,都放入第一個參數空對象中傳回

三、箭頭函數

3.1 簡化文法規定

1.去掉匿名函數的function,小括号和大括号之間使用箭頭

()=>{ }

不等價于匿名函數

var arr = [23,9,78,6,45];
arr.sort( /*function*/(a,b)=>{
    return a-b;
} )
           

2.箭頭函數的函數體中隻有一行代碼,可以省略

{}

如果隻有一行代碼且是return形式,必須省略

{}

return

arr.sort( (a,b)=>{return a-b} )

arr.sort( (a,b)=>a-b )

3.如果隻有一個形參,可以省略()

arr.map( (elem)=>{return elem} )

//↓

arr.map( elem=>elem )

示例:用箭頭函數求三個數的平均值

//方法一
var pingjun=(a,b,c)=> {
    return (a+b+c)/3;
};
//方法二
var pingjun= (a,b,c)=> (a+b+c)/3;

console.log(pingjun(1,2,3));
           

3.2 箭頭函數中的this

箭頭函數可讓函數内的this與函數外的this保持一緻!

  1. 如果函數中就不包含this,或剛好希望函數内的this與外部this保持一緻時,就可以改為箭頭函數
  2. 不希望函數内的this與函數外的this保持一緻時,都不能改為箭頭函數。

    比如: 對象中的方法就不能改為箭頭函數。

ES6中為對象的方法定義提供了一種專門的不帶function的簡寫:

var 對象名={
  屬性名: 屬性值, 
  方法名(){ ...  this.屬性名 ... }
}
           

既不帶:function,又不要加=>。

省略了function,又不等同于箭頭函數,不會影響内部的this!

示例:

原生bind()方法和箭頭函數方法将函數内的this改為函數外的this

var erya = {
	sname:"erya",
	friends:["yaya","yuanyuan"],
	
	//原生寫法:
	intr1:function(){
	    // erya調用,是以this->erya
	    this.friends.forEach(
	      function(ele) {
	        console.log(`${this.sname}的朋友是${ele}`);
	      }.bind(this)//綁定intr1作用域中的this
	    )
	},
	
	// 箭頭函數:可讓函數内的this與函數外的this保持一緻!
	// intr:function(){簡寫intr() 既省略了function,但是又不等同于箭頭函數,不會影響内部的this!
	intr() {
	  this.friends.forEach(
	    (ele)=>{
	      console.log(`${this.sname}的朋友是${ele}`);
	    }
	  )
	}
}
erya.intr1();
erya.intr();
           

圖解

①在erya對象中,intr方法有一個作用域,且’erya’調用了intr方法,是以intr的作用域中this->erya。

intr方法中還有一個回調函數,它也有一塊作用域

ES6——let、參數增強、箭頭函數、模闆字元串、for of和解構一、 let二、參數增強三、箭頭函數四、模闆字元串五、for of六、解構

②在回調函數作用域中this因自身無this,是以找到window.sname,window中sname找不到,是以傳回undefined

ES6——let、參數增強、箭頭函數、模闆字元串、for of和解構一、 let二、參數增強三、箭頭函數四、模闆字元串五、for of六、解構

解決方法一:使用bind()綁定this

.bind(this),将intr中的’this->erya’傳進來

ES6——let、參數增強、箭頭函數、模闆字元串、for of和解構一、 let二、參數增強三、箭頭函數四、模闆字元串五、for of六、解構

解決方法二:使用箭頭函數

箭頭函數相當于将回調函數的作用域推倒

ES6——let、參數增強、箭頭函數、模闆字元串、for of和解構一、 let二、參數增強三、箭頭函數四、模闆字元串五、for of六、解構

四、模闆字元串

解決了字元串的拼接問題

\` 模闆字元串 ${JS表達式} \`
           

反引号(`)辨別,它可以當作普通字元串使用,也可以用來定義多行字元串,或者在字元串中嵌入變量。

// 普通字元串
console.log(`In JavaScript '\n' is a line-feed.`)
 
// 多行字元串
console.log(`In JavaScript this is
not legal.`)

var name = "ERYA", time = "tomorrow";
console.log(`
Hello ${name}, 
how are you ${time}?
`);
           
ES6——let、參數增強、箭頭函數、模闆字元串、for of和解構一、 let二、參數增強三、箭頭函數四、模闆字元串五、for of六、解構

練習:聲明變量儲存一條員工的資料,格式為對象,包含的屬性有編号,姓名,性别(1/0),工資;最後列印出以下格式

var emp = {
  eid: 2,
  ename: 'erya',
  sex: 0,
  salary: 50000
};
console.log(`
  編号:${emp.eid}
  姓名:${emp.ename}
  性别:${emp.sex ? '男' : '女'}
  工資:${emp.salary.toFixed(2)}元
`);
           
ES6——let、參數增強、箭頭函數、模闆字元串、for of和解構一、 let二、參數增強三、箭頭函數四、模闆字元串五、for of六、解構

五、for of

周遊數字下标的數組或類數組對象

a. 普通for循環:

1). 優點: 既可周遊索引數組,又可以周遊類數組對象(arguments)

2). 缺點: 沒有可簡化的空間

加粗樣式

b. forEach:

1). 優點: 可以配合ES6的箭頭函數,很簡化

2). 缺點: 無法用于周遊類數組對象

隻要周遊數字下标的東西,都可用

for of

代替通for循環和forEach

for(var 變量  of  索引數組/類數組對象){
    //of會依次取出數組或類數組對象中每個屬性值
    //自動儲存of前的變量中
  }
           

缺點:

a. 無法獲得下标位置i,隻能獲得元素值

b. 無法控制周遊的順序或步調(不能倒序等)

for of 和 for in 和 forEach()

Column 1 Column 2 普通for forEach for of for in
數字下标 索引數組 ×
數字下标 類數組對象 × ×
自定義下标 關聯數組 × × ×
自定義下标 對象 × × ×

六、解構

定義:

将一個大的對象或數組中的個别成員提取出來單獨使用.

隻要一個大的對象或數組中,我們隻想用其中個别成員時,都要先将要使用的成員解構出來,再脫離開對象,單獨使用該成員。

6.1數組解構

從數組中提取出個别值,單獨使用

①先将等号左邊等着接元素值的變量裝扮成一個數組的樣子

var [變量1, 變量2] = 數組
           

②結果:下标對下标,自動指派

變量1 = 數組[0]
變量2 = 數組[1]
           

示例:

var arr = [
    {pid:1, pname:'yaya'},
    {pid:2, pname:'feifei'},
    {pid:3, pname:'yuanyuan'}
]
// 取出數組第一個和第二個對象
var [p1,p2] = arr;
//    0  1
console.log(p1);
console.log(p2);

//取出數組第一個和第三個對象
var [p1, , p3] = arr;
//   0      2
console.log(p1);
console.log(p3);
           
在這裡插入代碼片
           

6.2 對象解構

從對象中提取出個别成員(屬性或方法),單獨使用

①先将等号左邊等着接屬性值的變量裝扮成和右邊對象一模一樣的樣子,再用等号指派

var {屬性名1:變量1,屬性名2:變量2}=對象
           

隻要變量名和配對的屬性名相同,可隻寫一個,既配對又當變量!

var {屬性名1,屬性名2}=對象
           

②結果: 屬性對屬性

變量1=對象.屬性名1 的屬性值
變量2=對象.屬性名2 的屬性值
           

示例:

var db = {
   host:"127.0.0.1",
   port:3306,
   query() {
       console.log(`查詢商品清單`);
   },
   login() {
       console.log(`登入`);
   }
}
// 隻使用db對象的host和login
// 配對:變量  配對:變量
var {host:host, login:login} = db;

// ES6簡寫:
var {host, login} = db;

console.log(host);
console.log(login);
           

6.3 參數解構

隻要任意一個實參值都可能沒有,但是又要求實參值必須傳給指定的形參,順序不能亂,都可用參數解構:

步驟:

1.定義函數時:将所有形參變量裝扮成一個對象結構

一旦定義函數時,采用對象解構形式,則調用函數時,并須傳入一個對象結構,至少是一個{}

function 函數名({
  //配對 : 接實參值
  屬性名1: 形參1, 
  屬性名2: 形參2, 
 ... : ...
}){
  函數體
}

           

簡寫: 定義函數時,形參清單中,屬性名和形參名起相同名字,隻寫一個,既配對,又當形參變量名。

function 函數名({
  屬性名1=預設值1, 
  屬性名2=預設值2, 
  ... : ...
}){
  函數體
}

           

2.調用函數時:将所有實參值,裝扮成和定義函數時形參結構一模一樣的結構

函數名({
  //配對
  屬性名1: 實參值1, 
  屬性名2: 實參值2, 
  ... : ...
})

           

示例:

// 1.将所有形參變量裝扮成一個對象結構

function order({
    zhushi = "香辣雞腿堡",
    xiaochi = "雞薯條",
    yinliao= "可樂"
}) {
    console.log(`
    您點的套餐是:
        主食:${zhushi},
        小吃:${xiaochi},
        飲料:${yinliao}
    `);
}

//2.調用函數時:将所有實參值,裝扮成和定義函數時形參結構一模一樣的結構
// 一個都不換,也要加上{}
order({});

order({
    xiaochi:'紅豆派'
});

// 全都換
order({
    // 配對  實參值
    zhushi:"奧爾良烤腿堡",
    xiaochi:"扭扭薯條",
    yinliao:"雪碧"
});
           
ES6——let、參數增強、箭頭函數、模闆字元串、for of和解構一、 let二、參數增強三、箭頭函數四、模闆字元串五、for of六、解構