1, apply
code
Function.prototype.myApply = function () {
let thisObj = arguments[0] || window;
let args = arguments[1];
thisObj.fn = this;
let res = thisObj.fn(...args);
delete thisObj.fn;
return res;
}
test:
2, call
code
Function.prototype.myCall = function () {
let thisObj = arguments[0] || window;
let args = [...arguments].slice(1);
thisObj.fn = this;
let res = thisObj.fn(...args);
delete thisObj.fn;
return res;
}
test:
3, bind
code:
Function.prototype.myBind = function () {
let thisObj = arguments[0] || window;
let fn = this;
let args = [...arguments].slice(1);
return function F () {
if (this instanceof F) {
return new fn(...args, ...arguments)
} else {
return fn.apply(thisObj, args.concat([...arguments]));
}
}
}
test
4, 节流
code
function throttle (fn, time) {
let startTime = +new Date();
return function F () {
let lastTime = +new Date();
if (lastTime - startTime >= time) {
fn.apply(this, [...arguments]);
startTime = lastTime;
}
}
}
test
5, 防抖
code
function antiShake (fn, time, immediate) {
let time = null;
return function F () {
if (immediate) {
fn.apply(this, [...arguments]);
}
if (time) {
clearInterval(time);
}
setInterval(function () {
fn.apply(this, [...arguments]);
}, time);
}
}
6, 继承
code
function Animal(name) {
this.name = name;
}
Animal.prototype.say = function () {
console.log('my name is:' + this.name);
}
function Dog(name, age) {
Animal.apply(this, [name]);
this.age = age;
}
Dog.prototype = Object.create(Animal.prototype, {
constructor: {
value: Dog,
enumable: false,
writable: true,
configurable: true
}
});
var a = new Dog('xiaowang', 1)
code
7, instanceof
code
function myInstanceof(left, right) {
var r = right.prototype;
left = left.__proto__;
while(true) {
if (left === null) {
return false;
} else if (left === r) {
return true;
}
left = left.__proto__;
}
}
test
8, new
code
function myNew(fn, ...args) {
let obj = {};
obj.__proto__ = fn.prototype;
var res = fn.apply(obj, args);
return res instanceof Object ? res : obj;
}
test
9, 柯里化
code
function currying (fn, ...args) {
if (fn.length <= args.length) {
return fn(...args);
}
return function F() {
return currying(fn, ...args, ...arguments);
}
}
test
10,深拷贝
方法1
code
JSON.parse(JSON.stringify(obj))
test
缺点:
- 函数无法序列化
- 无法解决循环嵌套
- underfined 无法序列化
- symbol 无法序列化
##方法2
code
function messageChannelClone(obj) {
return new Promise((resolve, reject) => {
const {port1, port2} = new MessageChannel();
port2.onmessage = res => resolve(res.data);
port1.postMessage(obj);
})
}
var b = {
info: {
name: 'jin'
}
}
messageChannelClone(b).then(res=>{
console.log(res);
})
test
缺点:
- 函数无法序列化
- symbol 无法序列化
方法3 使用—lodash库
方法4 自己简单模拟实现
code
function clone(obj) {
let res;
if (obj && obj instanceof Object) {
res = Array.isArray(obj) ? [] : {};
for (let item in obj) {
res[i] = obj[item] instanceof Object ? clone(obj[item]) : obj[item];
}
} else {
res = obj;
}
return res;
}
11,JSON.parse
方法1
code
var a = '{name: "jiweijin"}'
eval('(' + a + ')')
方法2
var a = '{name: "jiweijin"}'
new Function('return ' + a)()
12,JSON.stringify
code
function jsonStringify(obj) {
let type = typeof obj;
if (type !== "object") {
if (/string|undefined|function/.test(type)) {
obj = '"' + obj + '"';
}
return String(obj);
} else {
let json = []
let arr = Array.isArray(obj)
for (let k in obj) {
let v = obj[k];
let type = typeof v;
if (/string|undefined|function/.test(type)) {
v = '"' + v + '"';
} else if (type === "object") {
v = jsonStringify(v);
}
json.push((arr ? "" : '"' + k + '":') + String(v));
}
return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}")
}
}
13,ajax
code
简单版
function myHttp(opt) {
let url = opt.url || '';
let method = opt.method || 'POST';
let data = opt.data || {};
let http = new XMLHttpRequest();
if (method.toUpperCase === 'GET') {
var dataStr = '';
for (let item in data) {
dataStr += item + '=' + data[item];
}
url += '?' + dataStr;
http.open(method, url);
http.send(null)
} else {
http.open(method, url)
http.send(data)
}
http.onreadystatechange = function () {
if (http.readystate === 4 && http.status === 200) {
opt.success(http.responseText)
}
}
}
14,promise
code
/**
* 1. new Promise时,需要传递一个 executor 执行器,执行器立刻执行
* 2. executor 接受两个参数,分别是 resolve 和 reject
* 3. promise 只能从 pending 到 rejected, 或者从 pending 到 fulfilled
* 4. promise 的状态一旦确认,就不会再改变
* 5. promise 都有 then 方法,then 接收两个参数,分别是 promise 成功的回调 onFulfilled,
* 和 promise 失败的回调 onRejected
* 6. 如果调用 then 时,promise已经成功,则执行 onFulfilled,并将promise的值作为参数传递进去。
* 如果promise已经失败,那么执行 onRejected, 并将 promise 失败的原因作为参数传递进去。
* 如果promise的状态是pending,需要将onFulfilled和onRejected函数存放起来,等待状态确定后,再依次将对应的函数执行(发布订阅)
* 7. then 的参数 onFulfilled 和 onRejected 可以缺省
* 8. promise 可以then多次,promise 的then 方法返回一个 promise
* 9. 如果 then 返回的是一个结果,那么就会把这个结果作为参数,传递给下一个then的成功的回调(onFulfilled)
* 10. 如果 then 中抛出了异常,那么就会把这个异常作为参数,传递给下一个then的失败的回调(onRejected)
* 11.如果 then 返回的是一个promise,那么需要等这个promise,那么会等这个promise执行完,promise如果成功,
* 就走下一个then的成功,如果失败,就走下一个then的失败
*/
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
function Promise(executor) {
let self = this;
self.status = PENDING;
self.onFulfilled = [];//成功的回调
self.onRejected = []; //失败的回调
//PromiseA+ 2.1
function resolve(value) {
if (self.status === PENDING) {
self.status = FULFILLED;
self.value = value;
self.onFulfilled.forEach(fn => fn());//PromiseA+ 2.2.6.1
}
}
function reject(reason) {
if (self.status === PENDING) {
self.status = REJECTED;
self.reason = reason;
self.onRejected.forEach(fn => fn());//PromiseA+ 2.2.6.2
}
}
try {
executor(resolve, reject);
} catch (e) {
reject(e);
}
}
Promise.prototype.then = function (onFulfilled, onRejected) {
//PromiseA+ 2.2.1 / PromiseA+ 2.2.5 / PromiseA+ 2.2.7.3 / PromiseA+ 2.2.7.4
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };
let self = this;
//PromiseA+ 2.2.7
let promise2 = new Promise((resolve, reject) => {
if (self.status === FULFILLED) {
//PromiseA+ 2.2.2
//PromiseA+ 2.2.4 --- setTimeout
setTimeout(() => {
try {
//PromiseA+ 2.2.7.1
let x = onFulfilled(self.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
//PromiseA+ 2.2.7.2
reject(e);
}
});
} else if (self.status === REJECTED) {
//PromiseA+ 2.2.3
setTimeout(() => {
try {
let x = onRejected(self.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
} else if (self.status === PENDING) {
self.onFulfilled.push(() => {
setTimeout(() => {
try {
let x = onFulfilled(self.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
self.onRejected.push(() => {
setTimeout(() => {
try {
let x = onRejected(self.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
}
});
return promise2;
}
function resolvePromise(promise2, x, resolve, reject) {
let self = this;
//PromiseA+ 2.3.1
if (promise2 === x) {
reject(new TypeError('Chaining cycle'));
}
if (x && typeof x === 'object' || typeof x === 'function') {
let used; //PromiseA+2.3.3.3.3 只能调用一次
try {
let then = x.then;
if (typeof then === 'function') {
//PromiseA+2.3.3
then.call(x, (y) => {
//PromiseA+2.3.3.1
if (used) return;
used = true;
resolvePromise(promise2, y, resolve, reject);
}, (r) => {
//PromiseA+2.3.3.2
if (used) return;
used = true;
reject(r);
});
}else{
//PromiseA+2.3.3.4
if (used) return;
used = true;
resolve(x);
}
} catch (e) {
//PromiseA+ 2.3.3.2
if (used) return;
used = true;
reject(e);
}
} else {
//PromiseA+ 2.3.3.4
resolve(x);
}
}