一.什么是es6
es6 是js語言的下一代標准,15年6月發布,也就是ECMAScript(2015)
ECMAScript就是JavaScript的國際標准,js是es的實現
es的歷史:
1996年11月,網景公司把js語言提交給國際標准組織ECMA,希望能成為國際標准推廣,1997年,ECMA發布ECMAScript 1.0
兼容的不是很好,但是寫起來方便也多了很多新的好玩的東西
編譯的話咱們就暫時先用咱們react使引入的哪個browser.js + type=‘text/bable’
不用的話也可能能用,但是有的地方就體現不出來了,還是編譯的好
為什么要有es6呢?自己想一下去吧..
編譯es6的方式:
1.瀏覽器編譯
2.gulp
二.let 和 const命令
1.let:聲明變量,聲明的是局部變量
用途及區別:ES6新增了let命令,用來聲明變量,類似於var ,但是聲明的變量只在let所在的代碼塊的內部有效
let不存在變量提升,這個要注意喲
- 暫時性的死區:
只要塊級作用域里存在let命令,它所聲明的變量就綁定這個區域,不在受外部的影響
- 不允許重復聲明
內部的數據有了let聲明過之后不允許重復聲明
2.塊級作用域
為什么需要塊級作用域:
es5只有全局作用域和函數作用域,這樣會造成一些不合理的地方
1>.內部數據覆蓋外部數據的情況
2>.用來計數的循環變量泄露成全局變量
雖然沒有專業的定義詞語來創建塊級作用域,但是只要內部用了let,就說明一個塊級作用域存在了,也就是說let命令為es6增加了塊級作用域
在以往我們為了讓變量執行完成后就銷毀不要浪費內存,會把大段的代碼放到立即執行函數里,而現在,我們只需要一個塊級作用域就好了
3.const :
聲明只讀常量 一旦聲明就不能進行更改,使用起來和var,let定義的的變量一樣,也是屬於塊級的定義方式,和let相似,也是不可重復聲明的
但是對象呀,數組呀都是可以改這個對象或者數組的東西的,因為真正保存的是地址,數組多個元素少個元素又不會改變地址
const person=Object.freeze({}); var cat=Object.freeze({});
賦值的時候可以用Object.freeze來凍結一個對象,使其內部的屬性和方法不能更改
4.全局對象屬性
全局對象是最頂層的對象,在瀏覽器環境指的是window對象,在node。js指的是global對象,在js語言里,所有變量都是全局對象的屬性,
es6規定,var 和function聲明的全局變量不屬於全局對象的屬性,let、const、class聲明的全局變量不屬於全局對象的屬性
二.對象的解構賦值
destructuring es6允許按照一定模式,從數組和對象里提取值,對變量進行賦值,這被成為解構賦值
1.數組的解構賦值
var [a,b,c]=[1,2,3];
指定默認值 注意:es6內部使用嚴格相等運算符(===)判斷一個位置上是否有值,所以如果一個數組成員不嚴格等於undefined,默認值是不會生效的
注意數組對應的如果不是數組的話就會報錯
2.對象的解構賦值
解構不僅可以用於數組,還可以用於對象 對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值
默認值生效的條件是,對象的屬性值嚴格等於undefined
3.函數參數的解構賦值
在以前的時候,當用戶傳入數組或者對象的時候,需要在函數內部對這個數組或者對象進行解構並且賦值、設置默認值 es6可以直接在函數的形參部分進行解構賦值和設置默認值
三:模板字符串
1.es6提供了又一種變量連接字符串的方法:
var food='蛋糕'; var drink='可樂'; var str=`今天的早餐是${food}和${drink}`;
2.es6覺得可以用一個函數來搞一搞這個字符串:
利用kitchen函數來操作拼接字符串的過程,注意的是這個函數的返回值就是最終的字符串 它接受兩個參數,第一個是一個數組,前幾位元素都是沒有拼接變量時的每一個小的部分,並且這個數組有個屬性叫raw,里面也會存放所有的元素 第二個參數可以用...的方式來接受所有的要拼接的變量
```
let food='蛋糕'; let drink='可樂'; let str=kitchen`今天的早餐是${food}和${drink}`; function kitchen (strings,...values) { console.log(strings.raw) console.log(values) return ... } console.log(str) ```
3.es6為字符串提供的幾個小方法
let str='今天是hige好日子,心想的事兒都能成' //1.判斷是否是以...開頭 console.log(str.startsWith('今天'))//true //2.判斷是否是以...結尾 console.log(str.endsWith('能成'))//true //3.判斷是否包含... console.log(str.includes('心'))//true
四:函數相關
1.設置函數參數的默認值
function fn (x=1,y=2) { return [x,y] } console.log(fn())
2.es6里面的... 叫法有兩個
1.展開操作符 spread 可以在一個數組或者一個對象里快速添加另一個數組的元素或者另一個對象的屬性方法,同名屬性會覆蓋 var fruit=['apple','banana']; var food=['meat',...fruit]; console.log(fruit); console.log(...fruit) console.log(food) var obj={ name:'xiu', age:13 } console.log(obj) console.log({x:1,...obj}) 2.剩余操作符 rest 多在函數里設置不確定數量的參數時使用 function lunch (meat,drink,...food) { console.log(meat) console.log(drink) console.log(food) console.log(...food) } lunch('beaf','cola','bread','baozi') 3.name屬性 es6為函數增加了一個name屬性,需要注意的是,匿名函數的name是引用的變量的名字,又賦值又有名字的函數name是函數自己的函數名 function myFn (argument) { } console.log(myFn.name)//myFn var yourFn=function(){ } console.log(yourFn.name)//yourFn var hisFn=function herFn(){ } console.log(hisFn.name)//herFn
4.es6新增了箭頭函數這樣的定義函數的方式,箭頭前面的是函數的參數,多個參數可以用()包裹,沒有參數也要寫(),箭頭后面的是函數的返回值,如果寫成{}包裹的話,就是函數體,需要返回值的時候要return
var fn=a=>a+1; // function fn (a) { // return a+1; // } console.log(fn(5))//6 var fn2=(a,b)=>{ return a+b; } // function fn2(a,b){ // return a+b; // } console.log(fn2(1,2))//3
五:變量添加屬性和方法
es6 覺得如果一個對象想擁有和一個變量的名字一樣的鍵名,並且值為這個變量的值的屬性的話,可以直接在鍵值對里直接寫一個變量名就好, 如果想設置一個方法,可以直接寫方法名(){}
let name='allen', age=13; let person={ name, age } console.log(person) var laugh=()=>{alert('hahaha')} let xiu={ laugh, sayHello(name='美女'){alert(`${name},你好`)}, ...person } xiu.laugh(); xiu.sayHello(); xiu.sayHello('baobao');
六:es6中對象的屬性名可以用變量的值去表示
let person={}; person.name='xiuxiu'; person.firstName='zhao'; person['second name']='wang'; let myname='third name' person[myname]='gao'; console.log(person)
七:幾個Object的方法
1. Object.is方法,可以做神奇的相等比較,類似為安格拉小姐
console.log(+0==-0)//true console.log(+0===-0)//true console.log(NaN==NaN)//false console.log(NaN===NaN)//false console.log(Object.is(+0,-0))//false console.log(Object.is(NaN,NaN))//true
2.Object.assign。可以用來把某一個對象里面的屬性復制另一個屬性里,同名會覆蓋,按照順序
var person={};
Object.assign(person,
{name:'zhaoxiu'}, {name:'wangxiu'}, {age:18} ) console.log(person)//{name:wangxiu,age:18}
3.Object.prototype相關
var a= Object.create(b)//把b作為原型來創建一個對象a Object.getPrototypeOf(a)//獲取a的原型 Object.setPrototypeOf(a,c);把a的原型設置為c var wang={ getName(){ return '王' } } var li={ getName(){ return '李' } } var xiu=Object.create(wang); console.log(xiu.getName())//王 console.log(Object.getPrototypeOf(xiu)==wang)//true Object.setPrototypeOf(xiu,li); console.log(xiu.getName())//李 console.log(Object.getPrototypeOf(xiu)==li)//true
通過{}.prototype可以來設置原型,但是輸出出來的卻是__proto__,es6覺得,那就直接設置__proto__吧
var wang={ getName(){ return '王' } } var li={ getName(){ return '李' } } var xiu={ __proto__:wang } console.log(xiu.getName())//王 console.log(Object.getPrototypeOf(xiu)==wang)//true xiu.__proto__=li console.log(xiu.getName())//李 console.log(Object.getPrototypeOf(xiu)==li)//true
在對象的方法里可以使用它原型的方法和屬性,這個時候在方法里用super來代表自己的原型
var wang={ getName(){ return '王' } } var xiu={ __proto__:wang, getFname(){ console.log(super.getName()) } } console.log(xiu) xiu.getFname()
八:class類
es6里引入了類的概念,可以通過class關鍵字來創建一個類,里面的contructor方法可以用來接受實例化時傳入的參數,還可以在class里寫一些自定義的方法,不需要加,哦
class person {
constructor(name){ this.name=name } say(){ console.log(this.name) } } var xiu=new person('xiu') console.log(xiu) //..... person name:"xiu" __proto__:Object constructor:person(name) say:say() __proto__:Object //............ xiu.say()///xiu
es6覺得獲取屬性和設置屬性的這些操作可以專門用set和get關鍵字來定義
class person { constructor(name){ this.name=name; this.hobby=[]; } get gethobby(){ return this.hobby; } set sethobby(hobby){ return this.hobby.push(hobby); } } var xiu=new person('xiu') console.log(xiu.hobby) //[] console.log(xiu.gethobby) //[] console.log(xiu.sethobby='sing') //sing console.log(xiu.hobby) // ['sing'] console.log(xiu.gethobby)// ['sing']
static 可以設置一個這個類自己的靜態方法,只有類可以調用,實例不可以調用
class person { constructor(name){ this.name=name; } say(word){ console.log(word) } static superSay(word){ console.log(word) } } var xiu=new person('xiu'); xiu.say('hello') //person.say('hello')//error //xiu.superSay('hello')//error person.superSay('hello')
es6的class里,可以用extentds來進行繼承class Student extends Person{ },但是如果父類通過constructor接受了參數,並且之類需要接受更多的參數,那么需要在子類的constructor里用super來給父類contructor傳遞參數,剩下的再自己使用
class Person { constructor(name,age){ this.name=name; this.age=age; } say(){ console.log(`${this.name},${this.age}`) } } new Person('xiu',18).say()//xiu,18 class Student extends Person{ constructor(name,age,sex){ super(name,age) this.sex=sex } } console.log(new Student('liu',13,'male'))
九:集合類型
-
1.es6新增了Set這個集合類型,類似與數組,但是還是有不少區別,比如,Set里不能有重復元素,重復元素不報錯但是也不會添加進去
通過new Set()來創建。初始參數是字符串 其他的要報錯,會把字符串拆開了作為元素
var _set=new Set('123') console.log(_set)//Set {"1", "2", "3"}
Set里不能有重復元素,重復元素不報錯但是也不會添加進去
var _set2=new Set('1223') console.log(_set2)//Set {"1", "2", "3"}
通過add方法來添加新元素 並且新添加是什么類型就是什么類型
var _set3=new Set('123') _set3.add(4) console.log(_set3)//Set {"1", "2", "3",4}
通過size來獲取元素個數
var _set4=new Set('123') console.log(_set4.size)//3 通過delete來刪除元素 var _set5=new Set('123') _set5.delete('3') console.log(_set5)//Set {"1", "2"} 通過has來判斷有沒有這個元素 var _set6=new Set('123') console.log(_set6.has('3'))//true 可以通過forEach來遍歷 var _set7=new Set('123') _set7.forEach((x,i)=>{ console.log(`${x},${i}`) }) // 1,1 // 2,2 // 3,3 通過clear來清除元素 var _set8=new Set('123') _set8.clear(); console.log(_set8)//Set {}
2.map,es6新增了map這樣的類型,和{}的區別就是可以用任何數據類型作為鍵值
let map=new Map(); //獲取一個map let [obj,fn,str]=[{},function () {},'hello']; map.set(obj,'obj') //設置map的鍵值對 map.set(fn,'fn') map.set(str,'str') console.log(map) console.log(map.size)//獲取map的鍵值對個數 console.log(map.get(obj)) //獲取map的鍵對應的值 console.log(map.delete(fn)); //刪除某一個鍵值對 console.log(map.has(fn)) //檢測是否包含某個鍵名 console.log(map.has(obj)) map.forEach((value,key)=>{ //可以用forEach來遍歷map console.log(value) console.log(key) }) map.clear(); //清空map的鍵值對 console.log(map)
10.模塊系統
在es6里引入了模塊的概念
export function square(x) { return x * x; }
import square from 'lib'; square(2)//4
export function square(x) { return x * x; } export function diag(x, y) { return sqrt(square(x) + square(y)); }
import { square, diag } from 'lib'; console.log(square(11)); // 121 console.log(diag(4, 3));
import * as lib from 'lib'; square = lib.square;