本文主要對工做中經常使用的數據類型的判斷
、遍歷
、轉化
三方面進行概括總結,也是面試中常常會遇到的考點,主要有如下幾種數據:面試
Number
String
Symbol
Set/Map
Function
Array(重點)
Object(重點)
判斷是否爲NaN數組
Number.isNaN(NaN) // true
isNaN( 'NaN' ) // true
Number.isNaN( 'NaN' ) // false 已對isNaN方法進行修正
複製代碼
判斷是否爲整數數據結構
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
複製代碼
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
複製代碼
保留指定小數位,會四捨五入,注意小數點與點運算符的區分dom
(5.673).toFixed(1) // 5.7
(5.673).toFixed(2) // 5.67
複製代碼
// 四捨五入
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
複製代碼
'abc'.includes('a') // true
複製代碼
'abc'.indexOf('b') // 1
複製代碼
'abc'.search('b') // 1
複製代碼
'abc'.match('b') // ['b']
複製代碼
去除先後空格函數
' abc '.trim() // 'abc'
複製代碼
以指定符號將字符串拆分爲數組ui
'a b c'.split(' ');
// ['a', 'b', '', '', 'c'] b和c之間有三個空格,因此三個空格會獲得夾着的兩個空格。
複製代碼
// 大小寫互換
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"
複製代碼
'a'.concat('bc') // 'abc'
複製代碼
'abcde'.slice(1, 2) // 'b'
複製代碼
// 參數若是是負數,會變爲0,一參大於二參則會互換位置
'abcde'.substring(2, -1) // 'ab' 至關於substring(0, 2)
複製代碼
'abcde'.substr(1, 2) // 'bc'
複製代碼
獨一無二的值,直接調用,不使用newthis
let s = Symbol()
typeof s // "symbol"
複製代碼
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)]
複製代碼
返回全部類型的鍵名spa
let obj = {
[Symbol('my_key')]: 1,
enum: 2,
nonEnum: 3
};
Reflect.ownKeys(obj) // ["enum", "nonEnum", Symbol(my_key)]
複製代碼
相似於數組,無重複值,參數爲具備
iterable接口
的數據。prototype
①add(value)
:添加某個值,返回 Set 結構自己。②delete(value)
:刪除某個值,返回一個布爾值,表示刪除是否成功。③has(value)
:返回一個布爾值,表示該值是否爲Set的成員。④clear()
:清除全部成員,沒有返回值。①keys()
:返回鍵名的遍歷器②values()
:返回鍵值的遍歷器③entries()
:返回鍵值對的遍歷器④forEach()
:使用回調函數遍歷每一個成員// 數組去重
[...new Set([1, 1, 2])] // [1, 2]
// 字符串去重
[...new Set('ababbc')].join('') // 'abc'
複製代碼
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]
複製代碼
相似於對象,也是鍵值對的集合,但「鍵」的範圍不限於字符串。
const map = new Map([
['name', '張三'],
['title', 'Author']
]);
map // {"name" => "張三", "title" => "Author"}
複製代碼
函數.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
複製代碼
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,因此不要在對象中使用箭頭函數
複製代碼
Array.isArray()
Object.prototype.toString.call()
萬能法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, 3].includes(2) // true
複製代碼
一參爲函數(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
多用於值,對象不可用
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()
返回刪除值
返回第一個符合條件的數組成員
[1, 4, -5, 10].find(n => n < 0)
// -5 注意不是返回數組
複製代碼
返回第一個符合條件的數組成員的位置
[1, 4, -5, 10].findIndex(n => n < 0)
// 2
複製代碼
返回數組的遍歷器對象,可用
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] ]
複製代碼
let [a, b, c = 3] = [1, [2], undefined]
a // 1
b // [2]
c // 3
複製代碼
let x = 1;
let y = 2;
[x, y] = [y, x];
複製代碼
DOM對象
、arguments類數組
、具備length屬性的對象
、字符串
等類數組轉爲真正的數組。Array.from()
Array.from
支持轉化具備Iterator接口
的對象,同時還支持轉化無Iterator接口
但相似數組的對象,即帶有length
屬性的對象。Array.from('hello') // [ "h", "e", "l", "l", "o" ]
複製代碼
Array.prototype.slice.call()
Array.prototype.slice.call('hello') // [ "h", "e", "l", "l", "o" ]
複製代碼
[...類數組]
Iterator接口
,所以只有Iterator接口
的對象才能夠用擴展運算符轉爲真正的數組。[...'hello'] // [ "h", "e", "l", "l", "o" ]
複製代碼
split
'hello'.split('') // [ "h", "e", "l", "l", "o" ]
複製代碼
[...arr]
let a = [...[1, 2]] // [1, 2]
複製代碼
Object.assign()
let a = Object.assign([], [1, 2]) // [1, 2]
複製代碼
slice()
let a = [1, 2].slice() // [1, 2]
複製代碼
concat()
let a = [].concat([1, 2]) // [1, 2]
複製代碼
concat
// 注意concat的參數若是傳的是數組,則會將數組的成員取出來與前者合併,而不是合併這個數組
[1].concat(2) // [1, 2]
[1].concat([2]) // 獲得[1, 2],而不是[1, [2]]
複製代碼
[...arr1, ...arr2]
[...[1, 2], ...[3, 4]] // [1, 2, 3, 4]
複製代碼
Set方法
[...new Set([1, 2, 3, 3])] // [1, 2, 3]
複製代碼
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]
複製代碼
function uni (data) {
return data.filter((value, index, arr) => arr.indexOf(value) === index)
}
uni([1, 2, 3, 3]) // [1, 2, 3]
複製代碼
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]
複製代碼
將數組
拉平
// 可設置拉平層數
[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]
複製代碼
比較兩個值是否相等,爲===
+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
複製代碼
同in做用
Reflect.has(Object, 'toString')
複製代碼
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] ]
複製代碼
// 設置變量及別名
let { x, y:m, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 報錯
m // 2
z // { a: 3, b: 4 }
複製代碼
{...}
// 數組轉對象
{...['x', 'y']} // {0: "x", 1: "y"}
// 字符串轉對象
{...'hello'} // {0: "h", 1: "e", 2: "l", 3: "l", 4: "o"}
複製代碼
Object.fromEntries
// 將鍵值對轉化爲對象
const entries = new Map([['foo', 'bar'], ['baz', 42]])
Object.fromEntries(entries) // { foo: "bar", baz: 42 }
複製代碼
{...}
{...{x: 1}, {...{y: 2}}} // {x: 1, y: 2}
複製代碼
Object.assign()
Object.assign({x: 1}, {y: 2}) // {x: 1, y: 2}
複製代碼
{...obj}
{...{x: 1}} // {x: 1}
複製代碼
Objcet.assign()
Object.assign({x: 1}, {y :2}} // {x: 1, y: 2}
複製代碼
JOSN.stringify()/JSON.parse()
let obj = {a: 1, b: {x: 3}}
JSON.parse(JSON.stringify(obj)) // {a: 1, b: {x: 3}}
複製代碼
遞歸拷貝
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
}
複製代碼