前端重點之數據處理

前言

本文主要對工做中經常使用的數據類型的判斷遍歷轉化三方面進行概括總結,也是面試中常常會遇到的考點,主要有如下幾種數據:面試

  1. Number
  2. String
  3. Symbol
  4. Set/Map
  5. Function
  6. Array(重點)
  7. Object(重點)

1、Number

1. 判斷

1.1 Number.isNaN()

判斷是否爲NaN數組

Number.isNaN(NaN)      // true
isNaN( 'NaN' )         // true
Number.isNaN( 'NaN' )  // false 已對isNaN方法進行修正
複製代碼

1.2 Number.isInteger()

判斷是否爲整數數據結構

Number.isInteger(25) // true
Number.isInteger(25.0) // true
Number.isInteger(25.1) // false

// 或者
function integer (num) {
    return typeof num === 'number' && num%1 === 0
}
integer(25)    // true
integer(25.1)  // false
複製代碼

2. 轉化

2.1 Number.parseInt()/Number.parseFloat()

ES6已將parseInt和parseFloat移植到Number對象上app

// ES5的寫法
parseInt('12.34')     // 12
parseFloat('123.45#') // 123.45

// ES6的寫法
Number.parseInt('12.34')     // 12
Number.parseFloat('123.45#') // 123.45

Number.parseInt === parseInt     // true
Number.parseFloat === parseFloat // true
複製代碼

2.2 toFixed()

保留指定小數位,會四捨五入,注意小數點與點運算符的區分dom

(5.673).toFixed(1)  // 5.7
(5.673).toFixed(2)  // 5.67
複製代碼

2.3 Math.round/Math.ceil/Math.floor/Math.trunc

// 四捨五入
Math.round(3.2)  // 3
Math.round(5.6) // 6

// 向上取整
Math.ceil(3.2)  // 4
Math.ceil(5.6)  // 6

// 向下取整
Math.floor(3.2)  // 3
Math.floor(5.6)  // 5

// 去除小數部分,返回整數部分
Math.trunc(4.9)     // 4
Math.trunc(-4.9)    // -4
Math.trunc(-0.1234) // -0
複製代碼

2、String

1. 判斷

1.1 includes() (數組也有此方法)

'abc'.includes('a')  // true
複製代碼

1.2 indexOf() 參數只能爲字符串(數組也有此方法)

'abc'.indexOf('b')  // 1
複製代碼

1.3 search() 參數可爲字符串或正則

'abc'.search('b')   // 1
複製代碼

1.4 match()

'abc'.match('b')   // ['b']
複製代碼

2. 轉化

3.1 trim()

去除先後空格函數

' abc '.trim()   // 'abc'
複製代碼

3.2 split()

以指定符號將字符串拆分爲數組ui

'a b c'.split(' ');  
// ['a', 'b', '', '', 'c'] b和c之間有三個空格,因此三個空格會獲得夾着的兩個空格。
複製代碼

3.3 replace()

// 大小寫互換
function change (str) {
    return str.replace(/([a-z]*)([A-Z]*)/g, (m, m1, m2) => {
        return m1.toUpperCase() + m2.toLowerCase()
    })
}
let str = 'Aabb_Cc'
change(str)   // "aABB_cC"
複製代碼

3.4 concat() (數組也有此方法)

'a'.concat('bc')  // 'abc'
複製代碼

3.5 slice(位置,位置) (數組也有此方法)

'abcde'.slice(1, 2)   // 'b' 
複製代碼

3.6 substring(位置,位置)

// 參數若是是負數,會變爲0,一參大於二參則會互換位置
'abcde'.substring(2, -1)   // 'ab' 至關於substring(0, 2) 
複製代碼

3.7 substr(位置,長度)

'abcde'.substr(1, 2)   // 'bc' 
複製代碼

3、Symbol

獨一無二的值,直接調用,不使用newthis

let s = Symbol()
typeof s  // "symbol"
複製代碼

1. 遍歷

1.1 Object.getOwnPropertySymbols()

const obj = {}
let a = Symbol('a')
let b = Symbol('b')

obj[a] = 'Hello'
obj[b] = 'World'

const objectSymbols = Object.getOwnPropertySymbols(obj)

objectSymbols  // [Symbol(a), Symbol(b)]
複製代碼

1.2 Reflect.ownKeys()

返回全部類型的鍵名spa

let obj = {
    [Symbol('my_key')]: 1,
    enum: 2,
    nonEnum: 3
};

Reflect.ownKeys(obj)  // ["enum", "nonEnum", Symbol(my_key)]
複製代碼

4、Set/Map

1. Set

相似於數組,無重複值,參數爲具備iterable接口的數據。prototype

1. 判斷

  • ①add(value):添加某個值,返回 Set 結構自己。
  • ②delete(value):刪除某個值,返回一個布爾值,表示刪除是否成功。
  • ③has(value):返回一個布爾值,表示該值是否爲Set的成員。
  • ④clear():清除全部成員,沒有返回值。

2. 遍歷

2.1 返回遍歷器

  • ①keys():返回鍵名的遍歷器
  • ②values():返回鍵值的遍歷器
  • ③entries():返回鍵值對的遍歷器
  • ④forEach():使用回調函數遍歷每一個成員

3. 轉化

3.1 去重

// 數組去重
[...new Set([1, 1, 2])]   // [1, 2]

// 字符串去重
[...new Set('ababbc')].join('')  // 'abc'
複製代碼

3.2 並集/交集/差集

let a = new Set([1, 2, 3])
let b = new Set([4, 3, 2])

// 並集
let union = [...new Set([...a, ...b])[]  // [1, 2, 3, 4]
// 或者
function uni (array) {
    let arr = []
    array.forEach(x => {
        if (!arr.includes(x)) {
            arr.push(x)
        } 
    })
    return arr
}
uni([...[1, 2, 3], ...[4, 3, 2]])  //  [1, 2, 3, 4]

// 交集
let intersect = [...new Set([...a].filter(x => b.has(x)))]  // [2, 3]
// 或者
[1, 2, 3].filter(x => [4, 3, 2].includes(x))  // [2, 3]

// 差集
let difference = [...new Set([...a].filter(x => !b.has(x)))] // [1]
// 或者
[1, 2, 3].filter(x => ![4, 3, 2].includes(x))  // [1]
複製代碼

2. Map

相似於對象,也是鍵值對的集合,但「鍵」的範圍不限於字符串。

const map = new Map([
  ['name', '張三'],
  ['title', 'Author']
]);
map       // {"name" => "張三", "title" => "Author"}
複製代碼

1. 判斷

  • ①size屬性
  • ②set(key, value)
  • ③get(key)
  • ④has(key)
  • ⑤delete(key)
  • ⑥clear()

2. 遍歷

  • keys():返回鍵名的遍歷器。
  • values():返回鍵值的遍歷器。
  • entries():返回全部成員的遍歷器。
  • forEach():遍歷 Map 的全部成員。

5、Function

1. 判斷

1.1 Function.prototype是函數,由JS引擎生成

函數.prototype.__proto__ === Object.prototype

Object instanceof Object // true Object.__proto__===Function.prototype Function.prototype.__proto__===Object.prototype
Function instanceof Function // true Function.__proto__===Function.prototype
Function instanceof Object // true Function.__proto__===Function.prototype Function.prototype.__proto__===Object.prototype
複製代碼

1.2 this指向

ES5中this永遠指向最後調用它的那個對象,可以使用call,apply,bind改變指向

// 手寫call
Function.prototype.mycall = function (obj) {
    if (typeof this !== 'function') {
        throw new TypeError('not funciton')
    }
    obj = obj || window
    obj.fn = this
    let arg = [...arguments].slice(1)
    let result = obj.fn(...arg)
    delete obj.fn
    return result
} 

// 手寫apply
Function.prototype.myapply = function (context) {
    if (typeof this !== 'function') {
        throw new TypeError('not funciton')
    }
    context = context || window
    context.fn = this
    let result
    if (arguments[1]) {
        result = context.fn(...arguments[1])
    } else {
        result = context.fn()
    }
    delete context.fn
    return result
}

// 手寫bind
Function.prototype.mybind = function (context) {
    if (typeof this !== 'function') {
        throw new TypeError('Error')
    }
    let _this = this
    let arg = [...arguments].slice(1)
    // 函數是能夠new的,因此要處理這個問題,使用組合繼承
    return function F() {
        if (this instanceof F) {
            return new _this(...arg, ...arguments)
        } else {
            return _this.apply(context, arg.concat(...arguments))
        }
    }
}
複製代碼

ES6的箭頭函數this指向定義它的對象,或者是箭頭函數所在的函數做用域

let obj = {
    a: 1,
    fn: () => {
        console.log(this.a)
    }
}
obj.fn()  // undefined 對象中的箭頭函數的this指向的是window,因此不要在對象中使用箭頭函數
複製代碼

6、Array

1. 判斷

1.1 是否爲數組

  1. Array.isArray()
  2. Object.prototype.toString.call() 萬能法
  3. instanceof
// 原理:實例的原型鏈上是否存在右側變量的原型
function instanceOf(left, right) {
    let leftValue = left.__proto__
    let rightValue = right.prototype
    while(true) {
        if (leftValue === null) {
            return false
        }
        if (leftValue === rightValue) {
            return true
        }
        leftValue = rightValue.__proto__
    }
}
複製代碼

1.2 includes(包含項, 起始位置)

判斷數組是否包含某個值,返回的是布爾值

[1, 2, 3].includes(2) // true
複製代碼

2. 遍歷

2.1 原數組不變

一參爲函數(value, index, arr) => {}, 二參爲this指向

  • map() 返回由rerurn值組成的數組,多用於將數據處理爲須要的格式

  • filter() 返回由return true的值組成的數組

  • every() 返回布爾值

  • some() 返回布爾值

  • forEach() 同for循環,無返回值

  • reduce() 多值變爲單值

// 返回最大值
[1, 2, 3].reduce((x, y) => x > y ? x : y )  // 3

// 返回最長字符串
['a', 'abc', 'ab'].reduce((x, y) => x.length > y.length ? x : y)  // 'abc'

// 求和
[1, 2, 3].reduce((x, y) => x + y)  // 6
複製代碼

多用於拼接拆分

  • join() 指定字符將數組拼接爲字符串

  • slice() 截取數組或字符串

  • concat() 鏈接數組或字符串

for循環

  • for

  • for in 多用於鍵

  • for of 多用於值,對象不可用

2.2 原數組改變

  • reverse() 反序

  • sort() 傳入排序參數

// 升序
[1, 3, 2].sort((x, y) => x - y)    // [1, 2, 3]

// 亂序
[1, 2, 3].sort(() => Math.random() - 0.5)    // [2, 3, 1]
複製代碼
  • splice(位置,個數,增長值) 可刪除或增長,返回刪除值

  • push() 返回長度

  • pop() 返回刪除值

  • unshift() 返回長度

  • shift() 返回刪除值

2.1 find((value, index, arr) => {}, this)

返回第一個符合條件的數組成員

[1, 4, -5, 10].find(n => n < 0)
// -5 注意不是返回數組
複製代碼

2.2 findIndex((value, index, arr) => {}, this)

返回第一個符合條件的數組成員的位置

[1, 4, -5, 10].findIndex(n => n < 0)
// 2 
複製代碼

2.3 keys()、values()、entries()

返回數組的遍歷器對象,可用for of或擴展運算符將值遍歷出來

for (let index of ['a', 'b'].keys()) {
  console.log(index);
}
// 0
// 1

for (let elem of ['a', 'b'].values()) {
  console.log(elem);
}
// 'a'
// 'b'

for (let [index, elem] of ['a', 'b'].entries()) {
  console.log(index, elem);
}
// 0 'a'
// 1 'b'

let arr = [1,2,3]; 
[...arr.values()];     // [1,2,3] 
[...arr.keys()];       // [0,1,2] 
[...arr.entries()];    // [ [0,1], [1,2], [2,3] ] 
複製代碼

3. 轉化

3.1 解構賦值

  1. 設置變量和默認值,undefined爲無值,null爲有值
let [a, b, c = 3] = [1, [2], undefined]
a  // 1
b  // [2]
c  // 3
複製代碼
  1. 交換變量值
let x = 1;
let y = 2;
[x, y] = [y, x];
複製代碼

3.2 類數組轉數組

  • DOM對象arguments類數組具備length屬性的對象字符串等類數組轉爲真正的數組。
  1. Array.from()
  • Array.from支持轉化具備Iterator接口的對象,同時還支持轉化無Iterator接口但相似數組的對象,即帶有length屬性的對象。
Array.from('hello')   // [ "h", "e", "l", "l", "o" ] 
複製代碼
  1. Array.prototype.slice.call()
Array.prototype.slice.call('hello')  // [ "h", "e", "l", "l", "o" ] 
複製代碼
  1. [...類數組]
  • 擴展運算符內部調用的是數據結構的Iterator接口,所以只有Iterator接口的對象才能夠用擴展運算符轉爲真正的數組。
[...'hello']   // [ "h", "e", "l", "l", "o" ] 
複製代碼
  1. split
'hello'.split('')  // [ "h", "e", "l", "l", "o" ] 
複製代碼

3.3 數組拷貝

  1. [...arr]
let a = [...[1, 2]]   // [1, 2] 
複製代碼
  1. Object.assign()
let a = Object.assign([], [1, 2])  // [1, 2]
複製代碼
  1. slice()
let a = [1, 2].slice()  // [1, 2]
複製代碼
  1. concat()
let a = [].concat([1, 2])  // [1, 2]
複製代碼

3.4 合併數組

  1. concat
// 注意concat的參數若是傳的是數組,則會將數組的成員取出來與前者合併,而不是合併這個數組
[1].concat(2)  // [1, 2]
[1].concat([2])  // 獲得[1, 2],而不是[1, [2]]
複製代碼
  1. [...arr1, ...arr2]
[...[1, 2], ...[3, 4]]  // [1, 2, 3, 4]
複製代碼

3.5 數組去重

  1. Set方法
[...new Set([1, 2, 3, 3])]  // [1, 2, 3]
複製代碼
  1. 數組遍歷法
function uni (array) {
    let arr = []
    array.forEach(x => {
        if (!arr.includes(x)) {
            arr.push(x)
        } 
    })
    return arr
}

uni([1, 2, 3, 3])  // [1, 2, 3]
複製代碼
  1. 數組下標法
function uni (data) {
    return data.filter((value, index, arr) => arr.indexOf(value) === index)
}

uni([1, 2, 3, 3])  // [1, 2, 3]
複製代碼
  1. 對象鍵值法
function uni (array) {
    let obj = {}
    let arr = []
    array.forEach(x => {
        if (!obj[x]) {
            arr.push(x)
            obj[x] = true
        }
    })
    return arr
}

uni([1, 2, 3, 3])  // [1, 2, 3]
複製代碼

3.6 數組排序

3.7 數組拉平

  1. flat(層數)

將數組拉平

// 可設置拉平層數
[1, 2, [3, [4, 5]]].flat(1)   // [1, 2, 3, [4, 5]]

// 層數不限使用Infinity
[1, [2, [3]]].flat(Infinity)  // [1, 2, 3]
複製代碼
function flat(arr){
    let array = []
    function handle(data) {
        if (Array.isArray(data)) {
            data.map(item => {
                Array.isArray(item) ? handle(item) : array.push(item)
            })
        } else {
            throw new TypeError('should be array')
        } 
    }
    handle(arr)
    return array
} 

flat([1, [2, [3]]])   // [1, 2, 3]
複製代碼

7、Object

1. 判斷

1.1 Object.is()

比較兩個值是否相等,爲===

+0 === -0      //true
NaN === NaN    // false

Object.is(+0, -0)    // false
Object.is(NaN, NaN)  // true
複製代碼

1.2 Reflect.has()

同in做用

Reflect.has(Object, 'toString') 
複製代碼

2. 遍歷

2.1 in (可遍歷自身及原型上的可枚舉和不可枚舉屬性)

2.2 for in (可遍歷自身及原型上的可枚舉屬性)

2.3 Object.getOwnPropertyNames (可遍歷自身可枚舉和不可枚舉屬性)

2.4 Object.hasOwnProperty() (可遍歷自身可枚舉和不可枚舉屬性)

2.5 Object.keys/Object.values/Object.entries (可遍歷自身可枚舉屬性)

2.6 Reflect.ownKeys() (等同於Object.getOwnPropertyNames與Object.getOwnPropertySymbols之和)

Object.keys({ foo: 'bar', baz: 42 })   // ["foo", "baz"]

Object.values({100: 'a', 2: 'b', 7: 'c'})  // ["b", "c", "a"]
// 屬性名爲數值的屬性,是按照數值大小,從小到大遍歷的,所以返回的順序是b、c、a

Object.entries({foo: 'bar', baz: 42})   // [ ["foo", "bar"], ["baz", 42] ]
複製代碼

3. 轉化

3.1 解構賦值

// 設置變量及別名
let { x, y:m, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 報錯
m // 2
z // { a: 3, b: 4 }
複製代碼

3.2 轉爲對象

  1. {...}
// 數組轉對象
{...['x', 'y']}  // {0: "x", 1: "y"}

// 字符串轉對象
{...'hello'}     // {0: "h", 1: "e", 2: "l", 3: "l", 4: "o"}
複製代碼
  1. Object.fromEntries
// 將鍵值對轉化爲對象
const entries = new Map([['foo', 'bar'], ['baz', 42]])

Object.fromEntries(entries)   // { foo: "bar", baz: 42 }
複製代碼

3.3 合併對象

  1. {...}
{...{x: 1}, {...{y: 2}}}  // {x: 1, y: 2}
複製代碼
  1. Object.assign()
Object.assign({x: 1}, {y: 2})  // {x: 1, y: 2}
複製代碼

3.4 對象拷貝

1. 淺拷貝

  1. {...obj}
{...{x: 1}}  // {x: 1}
複製代碼
  1. Objcet.assign()
Object.assign({x: 1}, {y :2}}  // {x: 1, y: 2}
複製代碼

2. 深拷貝

  1. JOSN.stringify()/JSON.parse()
let obj = {a: 1, b: {x: 3}}
JSON.parse(JSON.stringify(obj))  // {a: 1, b: {x: 3}}
複製代碼
  1. 遞歸拷貝
function deepClone(obj) {
    let copy = obj instanceof Array ? [] : {}
    for (let i in obj) {
        if (obj.hasOwnProperty(i)) {
            copy[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i]
        }
    }
    return copy
}
複製代碼

相關文章
相關標籤/搜索