1.数组扁平化 : 数组扁平化是指将一个多维数组变为一个一维数组
const res = [];
const fn = (arr) => {
for(let i=0;i<arr.length;i++){
if (Array.isArray(arr[i])){
fn(arr[i])
} else {
res.push(arr[i])
}
}
};
例子:
fn([1, [2, [3, [4, 5]]], 6])
2.数组去重
const unique = arr => {
let res=[];
for(let i=0;i<arr.length;i++){
if (res.indexOf(arr[i]) === -1){
res.push(arr[i])
}
}
return res
}
例子:
unique([1,1,3,4,5,6,5])
3.类数组转化为数组 : 类数组是具有length属性,但不具有数组原型上的方法。常见的类数组有arguments、DOM操作方法返回的结果。
1.[...document.querySelectorAll('div')];
2.Array.prototype.splice.call(document.querySelectorAll('div'));
4.filter
Array.prototype._filter = function(fn){
if(!Array.isArray(this)){
throw Error('type error')
}
if(typeof fn !== 'function'){
throw Error(fn + 'is not a function')
}
let res=[];
for(let i=0;i<this.length;i++){
if (fn(this[i], i, this)){
res.push(this[i])
}
}
return res;
}
例子:
function fun(e,i,a){
return e>2
}
var arr = [1,2,3,4];
var res = arr._filter(fun);
console.log(res)
5.map
Array.prototype._map = function(fn){
if (!Array.isArray(this)){
throw Error('type error')
}
if(typeof fn !== 'function'){
throw Error(fn + 'is not a function')
}
let res=[]
for(let i=0;i<this.length;i++){
res.push(fn(this[i], i, this))
}
return res;
}
function ArrReduce(e){
return e * 2;
}
var arr = [1,2,3];
var res = arr._map(ArrReduce)
console.log(res)
6.forEach
Array.prototype._forEach = function(fn){
if(!Array.isArray(this)){
throw Error('type error')
}
if(typeof fn !== 'function'){
throw Error(fn + 'is not a function')
}
for(let i=0;i<this.length;i++){
fn(this[i], i, this)
}
}
例子:
let list = [1,2,3,4,5]
list._forEach((elem,i)=>{
console.log(elem, i)
})
7.reduce
Array.prototype._reduce = function (fn, initValue) {
if (!Array.isArray(this)) {
throw Error("type error");
}
if (typeof fn !== "function") {
throw Error(fn + "is not a function");
}
let acc;
if (initValue) {
acc = initValue;
} else {
acc = 0;
}
for (let i = 0; i < this.length; i++) {
acc = fn(acc, this[i]);
}
return acc;
};
例子:
var arr = [1, 2, 3];
var res = arr._reduce(function (acc, el) {
return acc + el;
}, 2);
console.log(res);
8.apply
Function.prototype._apply = function(ctx=window, args){
if (typeof this !== 'function') {
throw Error(this + 'is not a function')
}
if(typeof ctx !== 'object'){
throw Error(this + 'is not a Object')
}
if(!Array.isArray(args)){
throw Error(args + 'is not a Array')
}
ctx['fn'] = this;
let res = ctx['fn'](...args);
delete ctx['fn'];
return res;
}
function fn(...args) {
console.log(this)
console.log(args)
}
fn._apply({x:10}, [1,2,3])
9.call
Function.prototype._call = function(ctx=window, ...args){
if (typeof this !== 'function') {
throw Error(this + 'is not a function')
}
if(typeof ctx !== 'object'){
throw Error(this + 'is not a Object')
}
ctx['fn'] = this;
let res = ctx['fn'](...args);
delete ctx['fn'];
return res;
}
例子:
function fn(...args) {
console.log(this)
console.log(...args)
}
fn._call({x:10}, 1,2,3)
10.bind
Function.prototype._bind = function(ctx=window) {
if (typeof this !== 'function') {
return;
}
var _self = this;
var args = Array.prototype.slice.call(arguments, 1)
var fn = function () {
// 检测 New
// 如果当前函数的this指向的是构造函数中的this 则判定为new 操作
var _this = this instanceof _self ? this : ctx;
return _self.apply(_this, args.concat(Array.prototype.slice.call(arguments)));
}
// 如果忽略掉原型连接这行代码,其原型对象并不等于原函数 _self 的原型,而是指定的传入的对象,不是 new 返回的对象
fn.prototype = this.prototype;
return fn;
}
例子:
function fn(...args) {
console.log(this)
console.log(...args)
}
let b = fn._bind({x:10}, 1,2,3)
b(4)
11.函数防抖: 触发高频时间后n秒内函数只会执行一次,如果n秒内高频时间再次触发,则重新计算时间。
function debounce (fn, delay){
let timer = null;
let that = this;
return function(){
if(timer){
clearTimeout(timer)
}
timer = setTimeout(function(){
fn.apply(that,arguments)
timer = null
},delay)
}
}
12.函数节流: 高频时间触发,但n秒内只会执行一次,所以节流会稀释函数的执行频率。
function throttle(fn,delay){
let timer = null;
return function(){
let that = this;
if(!timer){
timer = setTimeout(()=>{
fn.apply(that,arguments)
timer = null
}, delay)
}
}
}
13.函数柯里化: 指的是将一个接受多个参数的函数 变为 接受一个参数返回一个函数的固定形式,这样便于再次调用,例如f(1)(2)=3;
function f(){
const _args = [...arguments];
function fn(){
_args.push(...arguments);
return fn;
}
fn.toString = function(){
return _args.reduce((sum, cur) => sum + cur);
}
return fn
}
14.模拟new操作
function myNew(fn,...args) {
const obj = Object.create(null)
obj.__proto__ = fn.prototype
const result = fn.apply(obj, args)
const isObject = typeof result === 'object' && result !== null
const isFunction = typeof result === 'function'
if(isObject || isFunction) return result
return obj
}
例:
function P() {
const args = Array.prototype.slice.call(arguments, 0)
console.log(args)
}
var p = myNew(P, 1,2,3)
var p2 = new p(1,2,3)
15.手写ajax
function _ajax(url){
let p = new Promose((resolve, reject)=>{
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status === 200){
resolve(
JSON.parse(xhr.responseText);
)
} else if(xhr.status === 404){
reject(new Error('404 not found'))
}
}
}
xhr.send(null);
});
return p;
}
16.深拷贝
function deepClone(obj={}){
if(typeof obj !== 'object' || obj === null){
return obj;
}
let result;
if(obj instanceof Array){
result = [];
} else {
result = {};
}
for(let key in obj){
if(obj.hasOwnProperty(key)){
result[key]=deepClone(obj[key]);
}
}
return result;
}
17.instanceof
instanceof 原理:判断某个对象是否属于某个类型,或者是该类型的父类型祖先类型。
function myInstanceof(left, right) {
let leftValue = left.__proto__
let rightValue = right.prototype
while(leftValue) {
if(leftValue===rightValue) {
return true
}
leftValue = leftValue.__proto__
}
return false
}
例:
function P() {}
const p = new P()
console.log(p instanceof P)
console.log(myInstanceof(p, P))
18.Promsie.all
核心思路:
- 接收一个Promise实例的数组或者具有Iterator接口的对象作为参数
- 这个方法返回一个新的Promsie对象
- 遍历传入的参数,用Promsie.resolve()将参数进行包裹使其变成一个Promsie对象
- 参数所有回调成功才是成功,返回值数组与参数顺序一致,参数数组只要有一个失败则触发失败状态
function promiseAll(promsies) {
return new Promise((resolve, reject)=> {
if(!Array.isArray(promsies)) {
throw new Error('not Array')
}
let len = promsies.length
let count = 0
let result = []
for(let i=0;i<len;i++) {
Promise.resolve(promsies[i]).then(data=> {
result.push(data)
count++
if(count===len) {
return resolve(result)
}
}).catch(err=> {
return reject(err)
})
}
})
}
例:
const p1 = Promise.resolve(1)
const p2 = Promise.resolve(2)
Promise.all([p1, p2]).then(data=> {
console.log(data)
})
promiseAll([p1, p2]).then(data=> {
console.log(data)
})