Object.prototype.toString.call(array) === '[object Array]'
手写防抖
function debounce(fn,wait) {
var timeout = null; // 创建一个标记用来存放定时器的返回值
return function () {
if(timeout) clearTimeout(timeout); //清除定时器
//创建新的 setTimeout
timeout = setTimeout(fn(), wait);
};
}
// 处理函数
function handle() {
console.log(document.getElementById("kw").value);
}
//输入框事件
document.getElementById("kw").addEventListener('input', debounce(handle,5000));
手写节流
//fn是需要被节流的函数 delay是时间
function throttle(fn, delay) {
let flag= true
return function () {
let args=arguments;
if (!flag) {
return // 如果开关关闭了,那就直接不执行下边的代码
}
flag= false // 持续触发的话,run一直是false,就会停在上边的判断那里
setTimeout(() => {
fn.apply(this, args)
flag= true // 定时器到时间之后,会把开关打开,我们的函数就会被执行
}, delay)
}
}
手写浅拷贝
function shallowCopy(obj){
var data = {};
for (var key in obj){
if(obj.hasOwnProperty(key)){ // for in 循环,也会循环原型链上的属性,所以这里需要判断一下
//hasOwnProperty的相关知识点,查看下面的:相关知识点补充
data[key] = obj[key]
}
}
return data
}
手写深拷贝
function deepClone(obj){
let data = Array.isArray(obj)?[]:{};
if(obj && typeof obj==="object"){
for(key in obj){
if(obj.hasOwnProperty(key)){
//判断ojb子元素是否为对象,如果是,递归复制
if(obj[key]&&typeof obj[key] ==="object"){
data[key] = deepClone(obj[key]);
}else{
//如果不是,简单复制
data[key] = obj[key];
}
}
}
}
return data;
}
new
function _new(fn,...args){ // ...args为ES6展开符,也可以使用arguments
//先用Object创建一个空的对象,
const obj = Object.create(fn.prototype) //fn.prototype代表 用当前对象的原型去创建
//现在obj就代表Dog了,但是参数和this指向没有修改
const rel = fn.apply(obj,args)
//正常规定,如何fn返回的是null或undefined(也就是不返回内容),我们返回的是obj,否则返回rel
return rel instanceof Object ? rel : obj
}
set去重
let arr = [12,43,23,43,68,12];
//利用...把可以iterable的变为数组
let item = [...new Set(arr)];
console.log(item);//[12, 43, 23, 68]
apply
Function.prototype.apply = function(obj, arr) {
//将方法挂载到传入的上下文对象上
obj = obj || window;
obj.fn = this;
//调用函数
if (!arr) {
obj.fn();
} else {
if (!Array.isArray(arr)) {
throw new Error('必须传入数组!');
}
var result = eval('obj.fn(' + arr + ')');
}
delete obj.fn;
return result;
}
jsonp
function jsonp(url, data, callback) {
var ch = url.indexOf("?") == -1 ? "?" : "&";
var funcName = 'jsonp_' + Date.now() + Math.random().toString().substring(2)
//如果存在其他传入参数,需要进行拼接
if (typeof data === 'object') {
var tempArr = []
for (var key in data) {
var value = data[key]
tempArr.push(key + '=' + value)
}
data = tempArr.join('&')
}
var script = document.createElement('script')
script.src = url + ch + data + '&callback= ' + funcName
document.body.appendChild(script)
window[funcName] = function(data) {
callback(data)
//清除全局函数和script标签
delete window[funcName]
document.body.removeChild(script)
}
}
jsonp('https://www.baidu.com', {}, function(res) {
console.log(res)
})
promise的几个
promise
const PENDING = 'pending'
const RESOLVED = 'fulfilled'
const REJECTED = 'reject'
class tPromise {
constructor(executor) {
this.state = PENDING
this.data = undefined
//存储then的函数参数,现有resolv执行,后有then
this.callbacks = []
//在new实例对象时,这个this就变成实例,而resolve方法在类里面
try {
executor(this.resolve.bind(this), this.reject.bind(this))
//这一步是因为promise执行失败会提示错误而不会执行d出错误
} catch (error) {
this.reject(error);
}
}
resolve = value => {
setTimeout(() => {
if (this.state === PENDING) {
this.state = RESOLVED
this.data = value
if (this.callbacks.length > 0) {
this.callbacks.forEach(callbacksObj => {
callbacksObj(value)
})
}
}
})
}
reject = err => {
if (this.state === PENDING) {
this.state = REJECTED
this.data = err
if (this.callbacks.length > 0) {
this.callbacks.forEach(callbacksObj => {
callbacksObj(err.message)
})
}
}
}
then = (onResolved, onRejected) => {
return new Promise((resolve, reject) => {
//then后面的两个参数必须是函数
onResolved = typeof onResolved === 'function' ? onResolved : () => {};
onRejected = typeof onRejected === 'function' ? onRejected : () => {};
//如果值判断是成功还是失败,两者都不是就要等执行后菜执行
if (this.state === PENDING) {
this.callbacks.push(onResolved)
this.callbacks.push(onRejected)
}
if (this.state === RESOLVED) {
onResolved(this.data)
}
if (this.state === REJECTED) {
onRejected(this.data)
}
})
}
}
promise.all
Promise.prototype.all = (iterator) => {
let count = 0
let len = iterator.length
//输出的内容是数组,利用数组存放结果
let res = []
return new Promise((resolve, reject) => {
//这里用in而不用of是因为then是异步的,不一定按顺序,
//那么在加入数组中的时候顺序可能不一致
for (const item in iterator) {
//先转化为promise对象
Promise.resolve(iterator[item])
.then(value => {
res[item] = value;
if (++count == len)
resolve(res)
}, err => { reject(err) })
}
})
}
promise.race
Promise.prototype.race = (iterator) => {
return new Promise((resolve, reject) => {
for (const item of iterator) {
Promise.resolve(item)
.then(value => {
resolve(value)
}, err => { reject(err) })
}
})
}
promise.finally
Promise.prototype.finally = function (callback) {
let P = this.constructor;
return this.then(
value => P.resolve(callback()).then(() => value),
reason => P.resolve(callback()).then(() => { throw reason })
);
};
拍扁数组
var array = [5, 4, [2, 1, [4, 6]]];
var flat= function(input) {
var heap = input;
var res = [];
//heap-步一步把heap结构出来
while (heap.length!== 0) {
//首先取出第一个元素,
var target = heap.shift();
//判断它是否为数组,如果是数组,解构,并把值传进去,等系又可以扫描到他
if(Array.isArray(target)) {
heap.unshift(...target);
}else{
//否则直接加入res
res.unshift(target);
}
}
return res;
}
console. log(flat(array));
var arr=[1,2,[3, 4, [5,6,[7]]]];
function flatten(arr, deep){
return deep > 1 ? arr.reduce((prev, next) => prev.concat(
Array.isArray(next) ? flatten(next, deep - 1) : next), []
) : arr.slice()
}
flatten(arr, Infinity);
diff算法
ajax
function Ajax(url){
return new Promise((resolve,reject)=>{
const xhr=new XMLHttpRequest();
xhr.open('GET', url, true)
xhr.onreadystatechange=()=>{
if (xhr.readyState == 4) {
// 200-300 之间表示请求成功,304资源未变,取缓存
if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
resolve(xhr.responseText)
} else {
reject(new Error("error"))
}
}
}
xhr.send(null)
})
}
Ajax('./test.json').then(value=>{
console.log(value);
}).catch(err=>{
console.log(err);
})
reduce实现map
Array.prototype.rMap = function(fn) {
if (typeof fn === 'function') {
return this.reduce((prev, cur) => {
prev.push(fn(cur));
return prev
}, []);
}
}
var array = [1, 2, 3, 4, 5];
array = array.rMap((x) => x * 5);
console.log(array.toString());
use fetch
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)