本文主要对工做中经常使用的数据类型的判断
、遍历
、转化
三方面进行概括总结,也是面试中常常会遇到的考点,主要有如下几种数据:面试
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
}
复制代码