ES5 Object 對象方法擴充
ES5給Object擴充了一些靜态方法,常用的2個
- Object.create(prototype,[descriptors])
作用:以指定對象為原型建立新的對象
為新對象指定新的屬性,并對屬性進行描述
- value: 指定值
- writable: 辨別目前屬性值是否是可修改的,預設為false
- configurable: 辨別目前屬性是否可以被删除,預設為false
- enumerable: 辨別目前屬性是否能用 for in 枚舉 預設為false
- Object.defineProperties(object, descriptors)
作用: 為指定對象定義擴充多個屬性
- get: 用來擷取目前屬性值的回調函數
- set: 修改目前屬性值的觸發的額回調函數,并且實參即為修改後的值
- 存取器屬性:setter,getter一個用來存值,一個用來取值
ES5數組的擴充
- Array.prototype.indexOf(value) : 得到值在數組中的第一個下标
- Array.prototype.lastIndexOf(value): 得到值在數組中的最後一個下标
- Array.prototype.forEach(function(item, index){}): 周遊數組
- Array.prototype.map(function(item, index){}): 周遊數組傳回一個新的數組,傳回加工後的值
- Array.prototype.filter(function(item, index){}): 周遊過濾出一個新的子數組,傳回條件為true的值
var arr = [2, 4, 3, 2, 6, 5, 4]
console.log(arr.indexOf(4)) //1
console.log(arr.lastIndexOf(4)) // 7
arr.forEach(function(item, index) {
console.log(item, index)
})
var arr1 = arr.map(function(item, index) {
return item + 10
})
console.log(arr1) // [12, 14, 13, 12, 16, 15, 14]
var arr2 = arr.filter(function(item, index) {
return item > 3
})
console.log(arr2) //[4, 6, 5, 4]
ES5函數的擴充
- Function.prototype.bind(obj);
作用:将函數内的this綁定為obj,并并将函數傳回
bind的點: 綁定完this不會立即調用目前函數,而是将函數傳回
bind傳參數的方式同call一樣
- 差別bind()與call() apply()
都能指定函數中的this
call()/apply()是立即調用函數
bind()是将函數傳回
var obj = {username: 'lanfeng'}
function foo(data) {
console.log(this, data)
}
foo(); //window
//傳人參數的形式
foo.call(obj, 33) // 直接從第二個參數開始,依次傳入
foo.apply(obj, [33]) //第二個參數必須是數組,傳入參數放在數組裡
//bind的點: 綁定完this不會立即調用目前函數,而是将函數傳回
foo.bind(obj)()
// ----------
var obj = {username: 'lanfeng'}
setTimeout(function() {
console.log(this) //obj
}.bind(obj), 1000)
let、const 關鍵字
let 關鍵字
- 作用:與var類似,用于聲明一個變量
- 特點:
- 在塊作用域内有效
- 不能重複聲明
- 不會預處理,不存在提升
- 應用:
- 循環周遊加監聽
- 使用let取代var趨勢
let username = 'lanfeng'
const
- 作用:定義一個常量
- 特點:
- 不能修改
- 其它特點同let
- 應用:
儲存不用改變的資料
ES6箭頭函數
- 作用: 定義匿名函數
- 基本文法:
- 沒有參數:()=> console.log(‘xxxx’) , 小括号不能省略
- 一個參數:i => i+2
- 大于一個參數:(i, j) => i + j
- 函數體不用大括号:預設傳回結果
- 函數體如果有多個語句,需要用{}包圍,若有需要傳回的内容,需要手動傳回
- 使用場景: 多用來定義回調函數
- 箭頭函數的特點:
- 簡潔
- 箭頭函數沒有自己的this,箭頭函數的this不是調用的時候決定的,而是定義的時候處在的對象就是它的額this
- 擴充了解:外層函數的this看外層是否有函數,如果有,外層函數的this就是内部箭頭函數的this,如果沒有,則this是window
let fun = () => console.log('我是箭頭函數')
fun();
//形參的情況
// 1. 沒有形參的時候,小括号不能省略
let fun1 = ()=> console.log('我是箭頭函數')
// 2. 隻有一個形參的時候,小括号可以省略
let fun2 = (a) => console.log(a)
fun2('langfeng')
//3. 兩個及兩個以上的形參的時候,小括号不能省略
let fun3 = (x, y) => console.log(x, y)
fun3(25, 36)
// 函數體的情況
// 1. 函數體隻有一條語句或者是表達式的時候,大括号可以省略,會自動傳回語句執行的結果或者是表達式的結果
let fun4 = (x, y) => x+y
console.log(fun4(24, 36))
// 2. 函數體不止一條語句或者是表達式的額情況,{}不可以省略
let fun5 = (x, y) => {
console.log(x, y)
return x + y
}
console.log(fun5(35, 49))
ES6 promise對象
- 了解:
- promise對象:代表了未來某個将要發生的事件(通常是一個異步操作)
- 有了promise對象,可以将異步操作以同步操作的流程表達出來,避免了層層嵌套的回調函數
- ES6的promise是一個構造函數,用來生成promise執行個體
- 建立promise基本步驟(2步)
- 建立promise對象
let promise = new Promise((resolve, reject)) => {
//初始化promise狀态為pending
//執行異步操作
if(異步操作成功) {
resolve(value) //修改promise的狀态為fullfilled
} else {
reject(errMsg) //修改promise的狀态為rejected
}
}
- 調用promise的then()
promise.then(
result => console.log(result),
errorMsg => alert(errorMsg)
)
- promise對象的三個狀态
- pending: 初始化狀态
- fullfilled: 成功狀态
- rejected: 失敗狀态
ES6中的Symbol
- 概念:ES6中的添加了一種原始資料類型symbol(已有的原始資料類型:String, Number, boolean, undefined, null,Object)
- 特點:
- symbol屬性對應的值是唯一的,解決命名沖突問題
- symbol值不能與其它資料進行計算,包括同字元串拼串
- for in, for of周遊時不會周遊symbol屬性
- 使用:
- 調用symbol函數到symbol值
let symbol = Symbol();
let obj = {}
obj[symbol] = 'hello'
- 傳參辨別
let symbol = Symbol('one')
let symbol2 = Symbol('two')
console.log(symbol) // Symbol('one')
console.log(symbol2) // Symbol('two')
- 内置Symbol值
除了定義自己使用的Symbol值以外,ES6還提供了11個内置的Symbol值,指向語言内部使用的方法
Symbol.iterator
對象的Symbol.iterator屬性,指向該對象的預設周遊器方法
ES6中的async函數
- 概念:真正意義上去解決異步回調的問題,同步流程表達異步操作
- 本質:Generator的文法糖
- 文法:
async function foo() {
await 異步操作
await 異步操作
}
- 特點:
- 不需要Generator去調用next方法,遇到await等待,目前的異步操作完成就往下執行
- 傳回的總是Promise對象,可以用then方法進行下一步操作
- async 取代Generator函數的星号*,await取代Generator的yield
- 語意上更為明确,使用簡單
ES6中的class類
- 通過class定義類實作類的繼承
- 在類中通過constructor定義構造函數
- 通過new來建立類的執行個體
- 通過extends來實作類的繼承
- 通過super調用父類的構造方法
- 重寫從父類中繼承的一般方法
class Person {
//類的構造方法
constructor(name, age) {
this.name = name;
this.age = age
}
showName() {
console.log(this.name)
}
}
let person = new Person('kobe', 39)
console.log(person)
console.log(person.showName())
//子類
class StartPerson extends Person {
constructor(name, age) {
super(); //調用父類構造方法
}
}
let startPerson = new StartPerson('lanfeng', 28, 10000)
console.log(startPerson.showName()) // lanfeng
ES6中字元串的擴充
- includes(str): 判斷是否包含指定的字元串
- startsWith(str): 判斷是否以指定字元串開頭
- endsWith(str): 判斷是否以指定字元串結尾
- repeat(count): 重複指定次數
ES6中數組擴充方法
- Array.from(v): 将僞數組對象或者可周遊轉換為真熟組
- Array.of(v1, v2, v3): 将一系列值轉換成數組
- find(function(value, index, arr) { return true }) : 找出第一個滿足條件傳回true的元素
- findIIndex(function(value, index, arr) { retturn true }): 找出第一個滿足條件傳回true的元素下标
ES6中對象擴充方法
- Object.is(v1, v2)
判斷2個資料是否完全相等
- Object.assign(target, source1, source2…)
将源對象的屬性複制到目标對象上
- 直接操作__proto__屬性
let obj2 = {}
obj2._ proto_ = obj1
console.log(Object.is(0, -0)) // false
console.log(Object.is(NaN, NaN)) // true
數組和對象的克隆
- 對象複制
let obj = { username: 'lanfeng'}
let obj1 = obj; // obj1 複制了obj在堆記憶體的引用
- 常用的拷貝技術
- arr.concat():數組淺拷貝
- arr.slice(): 數組淺拷貝
- JSON.parse(JSON.stringify(arr/obj)) : 數組或對象深拷貝
- 淺拷貝包含函數資料的對象/數組
- 深拷貝包含函數資料的對象/數組
拷貝資料:
- 基本資料類型:拷貝後會生成一份新的資料,修改拷貝後的資料不會影響原資料
- 對象/數組:拷貝後不會生成新的資料,而是拷貝的是引用,修改拷貝以後的資料會影響原來的資料
//拷貝數組/對象,沒有生成新的數組而是複制了一份引用
let obj = {username: 'lanfeng', age: 30}
let obj1 = obj
console.log(obj1) // {username: "lanfeng", age: 30}
obj1.username = 'qiuqiu'
console.log(obj.username) //qiuqiu
拷貝資料的方法:
- 直接指派給一個變量. // 淺拷貝
- Object.assgin()
- Array.prototype.concat() // 淺拷貝
- Array.prototype.slice() // 淺拷貝
- JSON.parse(JSON.stringfy()) //深拷貝,拷貝的資料裡面不能有函數資料,處理不了
let obj = {username: 'lanfeng'}
let obj2 = Object.assign(obj)
console.log(obj2) // {username: "lanfeng"}
obj2.username = 'qiuqiu'
console.log(obj) // {username: "qiuqiu"}
// ---------
let arr = [1, 3, {username:'lanfeng'}]
let arr2 = arr.concat()
// console.log(arr2) //[1, 3, {username:'lanfeng'}]
arr2[1] = 'a'
console.log(arr) //[1, 3, {username:'lanfeng'}]
arr2[2].username = 'qiuqiu'
console.log(arr) //[1, 3, {username:'qiuqiu'}]
// ------
let arr = [1, 3, {username:'lanfeng'}]
let arr4 = JSON.parse(JSON.stringify(arr))
arr4[2].username = 'lanfeng2'
console.log(arr) // [1, 3, {username:'lanfeng'}]
淺拷貝(對象/數組)
特點:拷貝的引用,修改拷貝以後會影響原資料
深拷貝(深度克隆):拷貝的時候生成新的資料,修改拷貝以後不會影響原資料
在實作深拷貝之前,我們需要掌握以下知識點
如果判斷資料類型:
- typeof傳回的資料類型:String, Number, Boolean, undefined, object,function
- Object.prototype.toString.call(obj)
let result = 'abcd'
result = null;
result = [1, 3]
console.log(Object.prototype.toString.call(result).slice(8, -1)); // Array
for in 循環 對象(屬性名) 數組(下标)
let obj = {username: 'lanfeng', age: 39}
for(let i in obj) {
console.log(i)
}
let arr = [1,3, 'abc']
for(let i in arr) {
console.log(i)
}
定義檢測資料類型的功能函數
function checkType(target) {
return Object.prototype.toString.call(result).slice(8, -1)
}
實作深度克隆 ,一般針對數組或者對象
function checkedType(target) {
return Object.prototype.toString.call(target).slice(8, -1)
}
function clone(target) {
// 首先判斷拷貝資料的類型
//
let result, targetType = checkedType(target);
if(targetType === 'Object') {
result = {};
} else if(targetType === 'Array') {
result = [];
} else {
return target
}
// 周遊目标資料
for(let i in target) {
// 擷取周遊資料結構的每一項值
let value = target[i]
// 判斷目标結構裡的每一項值是否存在對象或數組
if(checkedType(value) === 'Object' || checkedType(value) === 'Array') {
// 繼續周遊擷取到value值
result[i] = clone(value)
} else {
// 擷取都的value值是最基本的資料類型或者是函數
result[i] = value
}
}
return result
}
let arr3 = [1,2, {username: 'lanfeng'}]
let arr4 = clone(arr3)
console.log(arr4)
arr4[2].username = 'qiuqiu'
console.log(arr3, arr4)
運作結果如下圖:
ES6中的set、map容器
- Set容器: 無序不可重複的多個value的集合體
- Set()
- Set(array)
- add(value)
- delete(value)
- has(key)
- clear()
- size
let set = new Set([1,2,4,2,5])
console.log(set)
- Map容器:無序的key不重複的多個key-value的集合體
- Map()
- Map(array)
- set(key, value) //添加
- get(key)
- delete(key)
- has(key)
- clear()
- size
ES6中的for of
for (let value of target) {} 循環周遊
- 周遊數組
- 周遊Set
- 周遊Map
- 周遊字元串
- 周遊僞數組
let set = new Set([1,2,4,5,2,3])
let arr = []
for(let i of set) {
arr.push(i)
}