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;
}
複製代碼
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;
}
複製代碼
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]));
}
}
}
複製代碼
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;
}
}
}
複製代碼
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);
}
}
複製代碼
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)
複製代碼
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__;
}
}
複製代碼
function myNew(fn, ...args) {
let obj = {};
obj.__proto__ = fn.prototype;
var res = fn.apply(obj, args);
return res instanceof Object ? res : obj;
}
複製代碼
function currying (fn, ...args) {
if (fn.length <= args.length) {
return fn(...args);
}
return function F() {
return currying(fn, ...args, ...arguments);
}
}
複製代碼
JSON.parse(JSON.stringify(obj))
複製代碼
##方法2ajax
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);
})
複製代碼
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;
}
複製代碼
var a = '{name: "jiweijin"}'
eval('(' + a + ')')
複製代碼
var a = '{name: "jiweijin"}'
new Function('return ' + a)()
複製代碼
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 ? "]" : "}")
}
}
複製代碼
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)
}
}
}
複製代碼
/**
* 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);
}
}
複製代碼