es6語(yǔ)法
1. 定義變量
var的缺點(diǎn):
?? ? ? 允許重復(fù)聲明
?? ? ? 不能聲明常量
?? ? ? 沒有塊級(jí)作用域
let的作用:
?? ? ? 不允許重復(fù)聲明
?? ? ? 不能聲明常量
?? ? ? 變量可以存在塊作用域中
const的作用
?? ? ? 不允許重復(fù)定義
?? ? ? 只能聲明常量
?? ? ? 常量可以存在塊作用域中
在es5中使用var可以重復(fù)聲明,let和const增加了代碼的嚴(yán)謹(jǐn)性,在重復(fù)聲明后會(huì)報(bào)出變量已聲明的錯(cuò)誤
var a=1
var a=2
console.log(a) //2
let a=1
let a=2
console.log(a) //SyntaxError:Identifier 'a' has already been declared
因?yàn)閑s5中沒有常量的概念,所以先說(shuō)下常量的含義,常量表示聲明后數(shù)值就不會(huì)發(fā)生改變。而const聲明的數(shù)據(jù)分為兩種基礎(chǔ)數(shù)據(jù)類型和引用數(shù)據(jù)類型?;A(chǔ)數(shù)據(jù)類型聲明后不能改變其數(shù)值,引用數(shù)據(jù)類型聲明后,不能改變其對(duì)象引用,但可以改變對(duì)象的內(nèi)容。
//基礎(chǔ)數(shù)據(jù)類型
const PI=3.1615926
PI=6
console.log(PI)//TypeError:Assignment to constant variable.
//引用數(shù)據(jù)類型
const user={name:"joker",sex:"male"}
user.sex=22
console.log(user)//{name: "joker", sex: "male", age: 22}
user={name:"lucy",sex:"female",age:"20"} //TypeError:Assignment to constant variable.
像java,c,c++都有塊級(jí)作用域,對(duì)于es5中的作用域只有全局作用域和函數(shù)作用域,而let和const的引入,讓javaScript也能使用塊級(jí)作用域.其中塊作用域聲明的變量為局部變量只在當(dāng)前作用域有效,而塊級(jí)作用域解決的一個(gè)問(wèn)題就是方法中不能獲取循環(huán)變量的當(dāng)前數(shù)值.
function createArr(){
var arr = new Array();
for(var i=0;i<4;i++){
arr[i]=function(){
return i;
}
}
return arr
}
var arrObj=createArr();
console.log(arrObj[0]()) //4
console.log(arrObj[1]()) //4
console.log(arrObj[2]()) //4
console.log(arrObj[3]()) //4
上述代碼中出現(xiàn)的這種問(wèn)題的原因是,javasript中變量的尋找是一級(jí)一級(jí)往上查詢的,當(dāng)執(zhí)行arrObj0方法時(shí),當(dāng)前作用域中沒有i變量只能往上級(jí)作用域中尋找。執(zhí)行arrObj0方法時(shí)for循環(huán)作用域中的i以循環(huán)完畢,因?yàn)闆]有塊級(jí)作用域來(lái)保存循環(huán)的i,此時(shí)尋找到的i為循環(huán)后的i既i=4。用偽代碼表示執(zhí)行循序?yàn)?/p>
var arr=new Array()
var i=0;
for(i;i<4;i++){
arr[i]=function(){
return "bind"
}
//arr[i]=function(){}實(shí)際只是將數(shù)據(jù)和方法綁定,實(shí)際并沒有的給arr[i]賦值
}
//當(dāng)調(diào)用方法時(shí)
arr[3]=function(){
return i
}
console.log(arr[3]())
解決上述問(wèn)題有三種方案,一種是使用立即執(zhí)行函數(shù),一種是外部建嵌套立即執(zhí)行函數(shù),一種是使用let。其中外部嵌套立即執(zhí)行函數(shù)和let原理相同,都是把i存放在了其需求作用域中.
//立即執(zhí)行函數(shù)
function createArr(){
var arr = new Array();
for(var i=0;i<4;i++){
arr[i]=(function(){
return i;
})(i)
}
return arr
}
...
//閉包
function createArr(){
var arr = new Array();
for(var i=0;i<4;i++){
(function(i){
arr[i]=function(){
return i;
}
})(i)
}
return arr
}
...
//使用let
function createArr(){
var arr = new Array();
for(let i=0;i<4;i++){
arr[i]=function(){
return i;
}
}
return arr
}
其中使用let提升作用域后的運(yùn)行流程偽代碼如下:
{
let i=1
arry[i]=function(){
return i
}
}
{
let i=2
arry[i]=function(){
return i
}
...
可以看出因?yàn)樘砑恿藟K級(jí)作用域,在方法獲取i時(shí)上一級(jí)作用域發(fā)生了改變.獲取到的i為保存在塊級(jí)作用域中的i。
2. 箭頭函數(shù)
es6中簡(jiǎn)化了匿名函數(shù)的寫法,其中使用箭頭函數(shù)簡(jiǎn)化了function的聲明。
寫法如下:
function(){}可以用()=>{}來(lái)替代,其中的在箭頭函數(shù)的()傳遞參數(shù),若function中只有一個(gè)參數(shù)則可以去掉箭頭函數(shù)的(),若funtion中只有return語(yǔ)句則可以去掉箭頭函數(shù)中的{},例子如下:
//普通寫法
function(){
}
functtion(parameter){
}
functtion(parameter1,parameter1){
}
function(parameter1,parameter1){
return parameter1;
}
//箭頭函數(shù)
()>{
}
parameter=>{
}
(parameter1,parameter1)=>{
}
(parameter1,parameter1)=>return parameter1
其中箭頭函數(shù)還改變了函數(shù)的this指向,箭頭函數(shù)中的this為從外層作用域中繼承的this。
3. 擴(kuò)展參數(shù)
es6引用了rect參數(shù),既用function(...argment)獲取多余參數(shù),其中argument是一個(gè)數(shù)組,將多余的參數(shù)存放到argment數(shù)組中。示例:
function test(a,b,...argument){
console.log(a) //1
console.log(b) //2
console.log(argument) //[3,4,5]
}
test(1,2,3,4,5)
擴(kuò)展參數(shù)之后不能在添加參數(shù)
function(a,...b,c){
}
//SyntaxError: Function statements require a function name
函數(shù)的length不包括擴(kuò)展參數(shù)
(function(a) {}).length // 1
(function(...a) {}).length // 0
(function(a, ...b) {}).length // 1
4. 解構(gòu)賦值
es6添加的了解構(gòu)賦值,就是對(duì)結(jié)構(gòu)相同的對(duì)個(gè)數(shù)據(jù)進(jìn)行賦值.其中需要保證等好兩邊的數(shù)據(jù)類型相同
//數(shù)組
let [a,b,c]=[1,2,3]
//對(duì)象
console.log(a,b,C)//1 2 3
let {arry,obj}={
arry:[1,2,3],
obj:{
name:"wangcai",
sex:"male"
}
}
console.log(arry,obj //[1,2,3] {name:"wangcai"}
其中解構(gòu)賦值能深層賦值
let {[a,b,c],{name}}={
arry:[1,2,3],
user:{
name:"wangcai"
}
}
console.log(a,b,c,name)// 1 2 3 wangcai
不完全解構(gòu)
let [[a]]=[[1,2]]
console.log(a) //1
let [ , , third] = ["one", "two", "three"];
console.log(third) // three
解構(gòu)賦值和擴(kuò)展參數(shù)
let {...argument}={
name:"joke",
age:"20"
}
console.log(argument)
如果解構(gòu)不成功則變量的值為undefined
let [name] = []
let [age, sex] = ['wangcai']
console.log(name,age,sex) //undefined "wangcai" undefined
5. 函數(shù)擴(kuò)展
函數(shù)的默認(rèn)參數(shù)
function test(x=5,y=10){
console.log(x,y)
}
test()//5 10
test(1)//1 10
test(1,20)//1 20
test(undefined,20)//5 20
與解構(gòu)參數(shù)使用
function test( {x,y}){
console.log(x,y)
}
test({x:6,y:20}) //6 20
function test( [x,y]){
console.log(x,y)
}
test([6,20]) //6 20
6. 數(shù)組擴(kuò)展
let a=[1,2,3]
let b=[4,5,6]
let c=[a,b]
console.log(c) //c[[1,2,3],[4,5,6]]
數(shù)組合并
let a=[1,2,3]
let b=[4,5,6]
let c=[...a,...b]
console.log(c) //[1,2,3,4,5,6]
map遍歷
//遍歷的是數(shù)組的item,把每個(gè)item進(jìn)行映射到新的數(shù)組中
let arry=[45,89,92,57,60,87]
let arry1=arry.map(item=>{
if(item<60){
return "不及格"
}
return "及格"
})
console.log(arry1)//["不及格", "及格", "及格", "不及格", "及格", "及格"]
reduce遍歷
//返回的計(jì)算的數(shù)值,第一個(gè)參數(shù)為每次計(jì)算的結(jié)果,第一次循環(huán)時(shí),第一個(gè)參數(shù)為第一個(gè)item
let arry=[10,20,30,40,50,60,70]
var avg=arry.reduce((result,nextItem,index)=>{
if(index===arry.length-1){
return (result+nextItem)/arry.length
}
return result+nextItem;
})
console.log(avg)
filter遍歷
//根據(jù)需求過(guò)濾數(shù)組,返回一個(gè)過(guò)濾之后的新數(shù)組
let array=[45,37,80,72,59,45]
var pass=array.filter(item=>{
if(item>60){
return item
}
})
console.log(pass)
forEach遍歷
//遍歷數(shù)組的每一項(xiàng)
let array=[45,37,80,72,59,45]
array.forEach((index,item)=>{
console.log('index:{'+index+"}-------value{"+item+"}")
})
7. 字符擴(kuò)展
字符模板
//字符串用``包裹使用字符模板
var name="wangcai"
var color="black"
var sex="male"
var str=`小狗的名字叫${name},顏色是${color},性別是${sex}`
console.log(str)
8.JSON
json對(duì)象轉(zhuǎn)字符串
var a={
name:"wangcai",
color:"black",
sex:"male"
}
var str=JSON.stringify(a)
console.log(str)
字符串轉(zhuǎn)json對(duì)象
var str='{"name":"wangcai","color":"white","age":1}'
var obj=JSON.parse(str)
console.log(obj)