一.let和const
我們通常用 let 和 const 來宣告,let 表示變數、const 表示常量。
1.沒有變數提升
console.log(a);
let a = 4;
// a is not defined
複製程式碼
2.不能重複申明
let a = 4;
let a = 5;
console.log(a);
// Identifier 'a' has already been declared
複製程式碼
3.具有塊級作用域(由花括號包裹的區域)
for(let i = 0; i < 3; i++){
console.log(i); //0 1 2
}
console.log(i);
//i is not defined
複製程式碼
4.臨時失效區(暫時性死區)
JS引擎掃描程式碼時,如果發現變數宣告,用var宣告變數時會將宣告提升到函式或全域性作用域的頂部。但是 let或者const,會將宣告關進一個小黑屋也是TDZ(暫時性死區),只有執行到變數宣告這句語句時,變數才會從小黑屋被放出來,才能安全使用這個變數。
var tt=123
if(true){
console.log(tt)//tt is not defined
let tt=456;
}
複製程式碼
一道面試題:
var funcs = []
for (var i = 0; i < 10; i++) {
funcs.push(function() { console.log(i) })
}
funcs.forEach(function(func) {
func()
})
複製程式碼
結果呢,就是列印十個10,怎樣才能列印出0到9呢?我們可以這樣改。
const funcs = []
for (let i = 0; i < 10; i++) {
funcs.push(function() {
console.log(i)
})
}
funcs.forEach(func => func())
複製程式碼
const 宣告的變數是常量,意思就是它的值被設定完成後就不能再修改了。 如果 const 的是一個物件,物件所包含的值是可以被修改的。就是物件所指向的地址不能改變,而變數成員是可以修改的。
const tt={name:"wangcai"};
tt.name="xiaoming";
console.log(tt.name)
//xiaoming
複製程式碼
二.箭頭函式
function() 函式的簡寫表示法,但它不繫結 this。
var object = {
name: "wangcai",
arrowGetName: () => this.name,
regularGetName: function() { return this.name },
arrowGetThis: () => this,
regularGetThis: function() { return this }
}
console.log(this.name)
//
console.log(object.arrowGetName());
//
console.log(object.arrowGetThis());
//window
console.log(this)
//window
console.log(object.regularGetName());
//wangcai
console.log(object.regularGetThis());
//object
複製程式碼
三.模板字串
如果使用模板字串表示多行字串,所有的空格和縮排都會被保留在輸出之中。
const t="hello"
console.log(`hh${t}`)
//hhhello
複製程式碼
console.log(`<div>
hahhah
</div>`)
//<div>
//hahhah
//</div>
複製程式碼
1.trim
除去字串空格的。
trim 左右空格都是去掉
trimLeft 左空格去掉
trimRight 右空格去掉
2.repeat
3.includes
var str="abc"
console.log(str.includes("a"))
//true
複製程式碼
4.startsWith和endsWidth
var str="abc def"
console.log(str.startsWidth("abc"))
//true
console.log(str.endsWidth("def"))
//true
複製程式碼
5.padStart和padEnd
var str="abc def"
console.log(str.padStart(15,"*"))
//"********abc def"
複製程式碼
var s=4
console.log(s.toFixed(2))
//4.00
console.log(s.toFixed(2).padStart(5,"0"))
//04.00
複製程式碼
四.解構賦值
//物件
let people = {
name: 'lux',
age: 20
}
const { name, age } = people
console.log(`${name} --- ${age}`)
//lux---20
//陣列
const color = ['red', 'blue']
const [first, second] = color
console.log(first)
//'red'
console.log(second)
//'blue'
複製程式碼
function f(x, y=12) {
return x + y;
}
console.log(f(3))//15
console.log(f(3,2))//5
複製程式碼
如果解構不成功,變數的值就等於undefined。如下:
let [foo] = [];
let [bar, foo] = [1];
複製程式碼
foo的值都會等於undefined。
let [x = 1, y = x] = [];
console.log(x, y)
// x=1; y=1
let [a = 1, b = a] = [2];
console.log(a, b)
// x=2; y=2
let [e = 1, f = e] = [1, 2];
console.log(e, f)
// x=1; y=2
let [t = d, d = 1] = [];
console.log(t, d)
// ReferenceError: d is not defined
複製程式碼
上面最後一個表示式之所以會報錯,是因為x用y做預設值時,y還沒有宣告。
字串也可以解構賦值。這是因為此時,字串被轉換成了一個類似陣列的物件。
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
複製程式碼
類似陣列的物件都有一個length屬性,因此還可以對這個屬性解構賦值。
let {length : len} = 'hello';
len // 5
複製程式碼
五.擴充套件運算子
let arr=[1,2,3]
let arr2=[...arr]
console.log(arr2)
//[1, 2, 3]
arr[0]=666
console.log(arr2)
//[1, 2, 3]
複製程式碼
陣列的複製---這裡是淺拷貝
可以利用擴充套件運算子,把類陣列轉成陣列
把一個類陣列轉成陣列有如下幾種方式:
Array.prototype.slice.call();
Array.from();
[...類陣列物件]
//陣列
const number = [1,2,3,4,5]
const [first, ...rest] = number
console.log(rest) //2,3,4,5
//物件
const user = {
username: 'lux',
gender: 'female',
age: 19,
address: 'peking'
}
const { username, ...rest } = user
console.log(rest) //{"address": "peking", "age": 19, "gender": "female"
}
複製程式碼
const first = {
a: 1,
b: 2,
c: 6,
}
const second = {
c: 3,
d: 4
}
const total = { ...first, ...second }
console.log(total) // { a: 1, b: 2, c: 3, d: 4 }
複製程式碼
有重複的屬性名,會覆蓋。
六.嚴格模式
之前學習的JS,語法非常靈活,JS中這個靈活的特性,弊大於利。後來增加了嚴格模式。使用嚴格模式的目的:規則,提高編譯效率。
怎麼去啟動嚴格模式: "use strict"
列舉如下幾條:
在嚴格模式下不能使用沒有var的變數。
在嚴格模式下不能8進位制的數字。
在嚴格模式下不能把函式定義在if語句中。
"use strict";
if(true){
function f(){
console.log("f.....")
}
}
f();
//f is not defined
複製程式碼
在嚴格模式下函式不能有重名的形參
"use strict";
function f(a,a){
console.log("f.....")
}
f();
// Uncaught SyntaxError: Duplicate parameter name not allowed in this context
複製程式碼
arguments不會自動反映函式引數的變化
"use strict";
function f(a,b){
console.log(a,b)
// 1 2
console.log(arguments[0],arguments[1])
//1 2
arguments[0]=111
arguments[1]=222
console.log(a,b)
//1 2
console.log(arguments[0],arguments[1])
//111 222
}
f(1,2);
複製程式碼
不能刪除不可刪除的屬性,否則報錯
禁止this指向全域性物件
"use strict";
function f(){
console.log(this)
}
f();
//undefined
複製程式碼
七.set
ES6 提供了新的資料結構Set。它類似於陣列,但是成員的值都是唯一的,沒有重複的值。Set 本身是一個建構函式,用來生成 Set 資料結構。
放一個陣列
var s1=new Set([1,2,3,"true"])
console.log(s1)
//
複製程式碼
結果為:
放一個物件
使用add()來新增,遍歷時,使用for each或者for of
var s1=new Set()
s1.add(1)
s1.add(2)
s1.add(3)
s1.forEach(item=>console.log(item))
//1 2 3
複製程式碼
set不是陣列,是一個像物件的陣列,是一個偽陣列。Set 例項的方法分為兩大類:操作方法(用於運算元據)和遍歷方法(用於遍歷成員)。
操作方法(用於運算元據)
add(value):新增某個值,返回 Set 結構本身。
delete(value):刪除某個值,返回一個布林值,表示刪除是否成功。
has(value):返回一個布林值,表示該值是否為Set的成員。
clear():清除所有成員,沒有返回值。
s.add(1).add(2).add(2);
// 注意2被加入了兩次
s.size // 2
s.has(1) // true
s.has(2) // true
s.has(3) // false
s.delete(2);
s.has(2) // false
複製程式碼
遍歷方法(用於遍歷成員)
keys() 返回鍵名的遍歷器
values() 返回鍵值的遍歷器
entries() 返回鍵值對的遍歷器
forEach() 使用回撥函式遍歷每個成員
keys方法、values方法、entries方法返回的都是遍歷器物件。由於 Set 結構沒有鍵名,只有鍵值(或者說鍵名和鍵值是同一個值),所以keys方法和values方法的行為完全一致。
let set = new Set(['red', 'green', 'blue']);
for (let item of set.keys()) {
console.log(item);
}
// red
// green
// blue
for (let item of set.values()) {
console.log(item);
}
// red
// green
// blue
for (let item of set.entries()) {
console.log(item);
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]
複製程式碼
八.map
Map 類似於物件,也是鍵值對的集合,但是“鍵”的範圍不限於字串,各種型別的值(包括物件)都可以當作鍵。
const m = new Map();
const o = {p: 'Hello World'};
m.set(o, 'content')
m.get(o) // "content"
m.has(o) // true
m.delete(o) // true
m.has(o) // false
複製程式碼
const map = new Map();
map.set(['a'], 555);
map.get(['a']) // undefined
複製程式碼
記憶體地址不一樣,所以是兩個值,返回undefined。
Map 結構的例項有以下屬性和操作方法。
屬性
size
size屬性返回 Map 結構的成員總數。
const map = new Map();
map.set('foo', true);
map.set('bar', false);
map.size // 2
複製程式碼
set(key, value)
set方法設定鍵名key對應的鍵值為value,然後返回整個 Map 結構。如果key已經有值,則鍵值會被更新。
get(key)
get方法讀取key對應的鍵值,如果找不到key,返回undefined。
has(key)
has方法返回一個布林值,表示某個鍵是否在當前 Map 物件之中。
delete(key)
delete方法刪除某個鍵,返回true。如果刪除失敗,返回false。
clear()
clear方法清除所有成員,沒有返回值。
操作方法
keys():返回鍵名的遍歷器。
values():返回鍵值的遍歷器。
entries():返回所有成員的遍歷器。
forEach():遍歷 Map 的所有成員。
map的操作方法和set類似,就不上程式碼啦。
九.class
從形式上,向主流的物件導向的語言靠攏。我們以前都是建立構造器,然後去new構造器,構造器就相當於一個類,在ES6中,就可以使用class來建立物件了。
function Nplayer(name,age,height){
this.name=name;
this.height=height
this.age=age
}
Nplayer.prototype.say=function(){
console.log(`我是${this.name},是NBA球員`)
}
var p1=new Nplayer("庫裡","30","191")
p1.say();
//我是庫裡,是NBA球員
複製程式碼
我們可以用class這樣寫:
class Nplayer {
constructor(name, age, height) {
this.name = name;
this.height = height
this.age = age
}
say() {
console.log(`我是${this.name},是NBA球員`)
}
}
var p1 = new Nplayer("庫裡", "30", "191")
p1.say();
//我是庫裡,是NBA球員
複製程式碼
使用extends實現繼承
注意:使用 extends 關鍵字來實現繼承
在子類中的構造器 constructor 中,必須要顯式呼叫父類的 super 方法,如果不呼叫,則 this 不可用
//父類
class Nplayer {
constructor(name, age, height) {
this.name = name;
this.height = height
this.age = age
}
say() {
console.log(`我是${this.name},是NBA球員`)
}
}
//子類
class MVP extends Nplayer {
constructor(name, age, height,year) {
super(name,age,height)
this.year = year
}
show() {
console.log(`我是${this.name},是${this.year}的球員`)
}
}
var p1 = new MVP("庫裡", "30", "191","2018")
p1.show();
//我是庫裡,是2018的球員
複製程式碼
類的靜態方法 static
直接通過類名來訪問的方法就是靜態方法。如:Math.abs();這裡的 abs()是靜態方法。 Array.isArray();isArray()是靜態方法, 在方法名前加 static 就可以了。這個就不多說了。
總結
關於es6的新增特性呢,還有很多,這裡就不一一列舉了,可以自行www.baidu.com,搜尋一下,阮一峰,哈哈。