new
function myNew(fn) {
var obj = {};
obj.__proto__ = fn.prototype;
var args = [].slice.call(arguments, 1);
var result = fn.apply(obj, args);
return typeof result === 'object' && result !== null ? result : obj;
}
function Foo(name, age) {
this.name = name;
this.age = age;
}
function Baz(name, age) {
this.name = name;
this.age = age;
return {a: 1};
}
myNew(Foo, 1, 2);
myNew(Baz, 1, 2);
JSON.stringfy
function jsonStringfy(obj) {
let type = typeof obj;
if (type !== 'object') {
if (/function|undefined|symbol/.test(type)) return undefined;
if (type === 'string') obj = `"${obj}"`;
return String(obj);
} else {
let json = [];
let isArr = Array.isArray(obj);
for (let k in obj) {
let v = obj[k];
let type = typeof v;
if (/function|undefined|symbol/.test(type)) continue;
if (type === 'string') {
v = `"${v}"`;
} else if (type === 'object') {
v = jsonStringfy(v);
}
json.push((isArr ? "" : `"${k}":`) + String(v));
}
return (isArr ? "[" : "{") + String(json) + (isArr ? "]" : "}")
}
}
JSON.parse
function jsonParse(str) {
return eval(`(${str})`)
}
function jsonParse(str) {
return (new Function('return ' + jsonStr))();
}
call
Function.prototype.call1 = function (context = window, ...args) {
if (this === Function.prototype) return undefined;
context.fn = this;
let result = context.fn(...args);
delete context.fn;
return result;
}
apply
Function.prototype.apply1 = function (context = window, args) {
if (this === Function.prototype) return undefined;
context.fn = this;
let result;
if (Array.isArray(args)) {
result = context.fn(...args);
} else {
result = context.fn();
}
delete context.fn;
return result;
}
bind
Function.prototype.bind1 = function (context, ...args1) {
if (typeof this !== 'function') {
throw new Error('Not a function');
}
let fn = this;
function ToBind(...args2) {
return fn.apply(
this instanceof F ? this : context || window,
args1.concat(args2)
)
}
function F() {};
F.prototype = fn.prototype;
ToBind.prototype = new F();
return ToBind;
}
继承
function Parent(name) {
this.name = name;
}
Parent.prototype.sayName = function() {
console.log('name:', this.name);
}
function Children(name, age) {
Parent.call(this, name);
this.age = age;
}
function create(obj) {
function F() {};
F.prototype = obj;
return new F();
}
Children.prototype = create(Parent.prototype);
Children.prototype.sayAge = function() {
console.log('age:', this.age);
}
Object.defineProperty(Children.prototype, 'constructor', {
value: Children,
enumerable: false,
writable: true,
configurable: true,
})
var child = new Children('Foo', 20);
child.sayAge();
child.sayName();
柯里化
function curry(fn) {
let args = Array.prototype.slice.call(arguments, 1);
return function () {
let innerArgs = Array.prototype.slice.call(arguments);
return fn.apply(this, args.concat(innerArgs));
}
}
function multiFn(a, b, c) {
return a * b * c;
}
function curry1(fn) {
let length = fn.length;
let args1 = Array.prototype.slice.call(arguments, 1);
return function () {
let args2 = Array.prototype.slice.call(arguments);
let args = args1.concat(args2);
if (args.length >= length) {
return fn.apply(this, args);
} else {
return curry1(fn, ...args);
}
}
}
let multi = curry1(multiFn);
multi(2,3,4);
multi(2)(3)(4);
function multiFn() {
let args = Array.prototype.slice.call(arguments);
return args.reduce((pre, cur) => pre * cur);
}
function curry2(fn) {
let args1 = Array.prototype.slice.call(arguments, 1);
return function () {
let arg2 = Array.prototype.slice.call(arguments);
if (arguments.length === 0) {
return fn.apply(this, args1.concat(arg2));
} else {
return curry2(fn, ...args1.concat(arg2));
}
}
}
let multi = curry2(multiFn);
multi(2)(3)(4)();
Promise
const PENDING = "pending"
const FULFILLED = "fulfilled"
const REJECTED = "rejected"
function Promise(f) {
this.state = PENDING;
this.value = undefined;
this.reason = undefined;
const resolve = value => {
if (value === this) {
throw new TypeError('Can not fulfill itself');
}
if (value instanceof Promise) {
return value.then(resolve, reject);
}
setTimeout(() => {
if (this.state === PENDING) {
this.state = FULFILLED;
this.value = value;
}
})
}
const reject = reason => {
setTimeout(() => {
if (this.state === PENDING) {
this.state = REJECTED;
this.reason = reason;
}
})
}
try {
f(resolve, reject)
} catch (error) {
reject(error)
}
}
Promise.prototype.then = function(onFulfilled, onRejected) {
if (this.state === FULFILLED) {
onFulfilled(this.value);
} else if (this.state === REJECTED) {
onRejected(this.reason);
}
}
var promise = new Promise((resolve, reject) => resolve(1))
promise.then(v => console.log(v));
const isFunction = obj => typeof obj === 'function'
const isObject = obj => !!(obj && typeof obj === 'object')
const isThenable = obj => (isFunction(obj) || isObject(obj)) && 'then' in obj
const isPromise = promise => promise instanceof Promise
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
function Promise(f) {
this.result = null
this.state = PENDING
this.callbacks = []
let onFulfilled = value => transition(this, FULFILLED, value)
let onRejected = reason => transition(this, REJECTED, reason)
let ignore = false
let resolve = value => {
if (ignore) return
ignore = true
resolvePromise(this, value, onFulfilled, onRejected)
}
let reject = reason => {
if (ignore) return
ignore = true
onRejected(reason)
}
try {
f(resolve, reject)
} catch (error) {
reject(error)
}
}
Promise.prototype.then = function(onFulfilled, onRejected) {
return new Promise((resolve, reject) => {
let callback = { onFulfilled, onRejected, resolve, reject }
if (this.state === PENDING) {
this.callbacks.push(callback)
} else {
setTimeout(() => handleCallback(callback, this.state, this.result), 0)
}
})
}
const handleCallback = (callback, state, result) => {
let { onFulfilled, onRejected, resolve, reject } = callback
try {
if (state === FULFILLED) {
isFunction(onFulfilled) ? resolve(onFulfilled(result)) : resolve(result)
} else if (state === REJECTED) {
isFunction(onRejected) ? resolve(onRejected(result)) : reject(result)
}
} catch (error) {
reject(error)
}
}
const handleCallbacks = (callbacks, state, result) => {
while (callbacks.length) handleCallback(callbacks.shift(), state, result)
}
const transition = (promise, state, result) => {
if (promise.state !== PENDING) return
promise.state = state
promise.result = result
setTimeout(() => handleCallbacks(promise.callbacks, state, result), 0)
}
const resolvePromise = (promise, result, resolve, reject) => {
if (result === promise) {
let reason = new TypeError('Can not fulfill promise with itself')
return reject(reason)
}
if (isPromise(result)) {
return result.then(resolve, reject)
}
if (isThenable(result)) {
try {
let then = result.then
if (isFunction(then)) {
return new Promise(then.bind(result)).then(resolve, reject)
}
} catch (error) {
return reject(error)
}
}
resolve(result)
}
防抖函数
function debounce(fn, wait, immediate) {
let timer = null;
return function() {
if (timer) clearTimeout(timer);
if (immediate && !timer) fn.apply(this, arguments);
timer = setTimeout(() => {
fn.apply(this, arguments);
}, wait)
}
}
节流函数
function throttle(fn, interval) {
let last = 0;
let timer = null;
return function() {
let now = Date.now();
let delay = interval - (now - last);
if (delay <= 0) {
if (timer) {
clearTimeout(timer);
timer = null;
}
fn.apply(this, arguments);
} else {
timer = setTimeout(() => {
fn.apply(this, arguments);
}, delay)
}
}
}
深拷贝
function deepClone(obj) {
if (typeof obj !== 'object' || obj === null) return obj;
let res = Array.isArray(obj) ? [] : {};
for (let k in obj) {
if (typeof obj[k] === 'object') {
res[k] = deepClone(obj[k]);
} else {
res[k] = obj[k];
}
}
return res;
}
instanceof
function instanceOf(obj, ctor) {
let proto = obj.__proto__
let prototype = ctor.prototype
while (true) {
if (proto === null) return false
if (proto === prototype) return true
proto = proto.__proto__
}
}
参考