欲望请放过脆弱的我

image

几个实现。。。

前言

前一段时间忙着找工作,好久没更新,更新几个年前看到的几个实现js,当然面试官有的也问到过几个,没事自己写写还是挺有意思,这次当一个回顾吧。

实现一个new

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//new

function _new (fun){
var res = {};
if(fun.proptype != null){
res.__proto__ = fun.proptype
};
var ret = fun.apply(res,Array.from(arguments).slice(1)); //若构造函数返回指定类型 则返回ret
if ((typeof ret === "object" || typeof ret === "function") && ret !== null) {
return ret;
}
return res;
}

//test new
function Parent (name){
this.name = name;
this.arr = [1,2,3];
//return function b() {} //若构造函数返回指定类型 则返回[Function: b]
};

console.log(_new(Parent,'fqm')) // { name: 'fqm', arr: [ 1, 2, 3 ] }

实现一个Object.create

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//Object.create

//方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
//第二个参数可选即其自身定义的属性

function _objectCreate(proto){
function f(){};
f.prototype = proto;
return new f();
}

//test _objectCreate

var obj = _objectCreate({'objectCreate':123})
console.log(obj.__proto__) //{ objectCreate: 123 }

实现一个call

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//call

Function.prototype._call = function(target){
target.fn = this;
var arg = Array.from(arguments).slice(1);
var res = target.fn(...arg);
delete target.fn;
return res;
}

//test call
let foo = {
value: 1
}

function bar(name, age) {
console.log(name)
console.log(age)
console.log(this.value);
}
console.log(bar._call(foo, 'black', '18')) // black 18 1 undefined

实现一个apply

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//apply

Function.prototype._apply = function(target){
target.fn = this;
var arg = arguments[1]; //传递的已经是数组
var res = target.fn(...arg);
delete target.fn;
return res;
}

//test apply
let foo1 = {
value: 1
}

function bar(name, age) {
console.log(name)
console.log(age)
console.log(this.value);
}
console.log(bar._apply(foo1, ['apply', '18'])) // black 18 1 undefined

实现一个bind

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//bind

Function.prototype._bind = function(target){
var arg = Array.from(arguments).slice(1);
var that = this;
function f (){
arg = [...arg,...arguments];
that.apply(target,arg)
}
f.prototype = Object.create(this.prototype);//指定新函数的prototype与原函数prototype相同
return f;
}

//test bind

var bindObj = {
name:'fqm'
}

function testBind(){
console.log(this.name)
console.log(arguments)
}

var Bindfun = testBind._bind(bindObj,23)

Bindfun(11) //fqm { '0': 23, '1': 11 }

实现一个promise

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//_Promise

function _Promise(constructor){
var that = this;
that.status = 'pending';
that.result = undefined; //resolve
that.reason = undefined; //reject
function resolve(value){
if(that.status === 'pending'){
that.result = value;
that.status = 'resolved'
}
}
function reject(value){
if(that.status === 'pending'){
that.reason = value;
that.status = 'rejected'
}
}

try{
constructor(resolve,reject)
}catch(e){
reject(e)
}
}

_Promise.prototype.then = function(onFullfilled,onRejected){
var that = this;
switch(that.status){
case "resolved":
onFullfilled(that.result);
break;
case "rejected":
onRejected(that.reason);
break;
default:
}
}

//test _Promise

var p = new _Promise((res,rej) => {res(100)});

p.then(res => {console.log(res)}) //100

实现一个深拷贝

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function _deepCopy(arg){
let filterArr = ['[object Array]','[object Object]'];
let res = filterArr.includes(Object.prototype.toString.call(arg)) ? Array.isArray(arg) ? [] : {} : arg;
for(let i in arg){
res[i] = filterArr.includes(Object.prototype.toString.call(arg[i])) ? _deepCopy(arg[i]) : arg[i]
}
return res;
}

//test _deepCopy
var a = {
name:'fu',
money:{'rmb':100,'$':999},
reg:new RegExp(/^1(3|4|5|7|8)\d{9}$/),
fun:function(){},
err: new Error('我是一个错误'),
date:new Date(0)

};
var b = _deepCopy(a);
console.log(a.money === b.money) //false
console.log(a.reg === b.reg) //true
console.log(a.date === b.date) //true
console.log(a.fun === b.fun) //true
console.log(a.err === b.err) //true

实现一个JSON.stringify

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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 ? "]" : "}")
}
}

//test _jsonStringify

console.log(_jsonStringify({x : 5})) // "{"x":5}"
console.log(_jsonStringify([1, "false", false])) // "[1,"false",false]"
console.log(_jsonStringify({b: undefined})) // "{"b":"undefined"}"

实现一个JSON.parse

1
2
3
4
5
6
7
8
9
10
//JSON.parse

function _jsonStringParse (str){
var res = new Function('return' + str);
return res()
}

//test _jsonStringParse

console.log(_jsonStringParse('{ "age": 20, "name": "jack" }')) //{ age: 20, name: 'jack' }

实现一个instanceOf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//instanceof

function _instanceOf(target,origin){
let proto = target.__proto__;
let proptype = origin.prototype;
while(true){
if(proto == null) return false;
if(proto == proptype) return true;
//若本次查找无结果,则沿着原型链向上查找
proto = proto.__proto__;
}
}

//test instanceof

console.log(_instanceOf([1,2],Array))

实现一个防抖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//debounce

function _debounce(fn,wait,immediate){
let timer;
return function(){
var arg = arguments;
if(immediate) fn.apply(this,arg);
if(timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this,arg);
},wait)
}
}

//test debounce

function event(){
console.log("fqm");
}
window.addEventListener('scroll',debounce(event,500));

实现一个节流

1
2
3
4
5
6
7
8
9
10
11
12
//Throttling

function _Throttling(fn,wait){
let prev = new Date();
return function(){
let now = new Date();
if(now - prev > wait){
fn.apply(this,arguments);
prev = new Date();
}
};
}

实现一个函数柯里化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//curry
function curry(fn, args) {
var length = fn.length;
var args = args || [];
return function(){
newArgs = [...args,...Array.from(arguments)];
if (newArgs.length < length) {
return curry.call(this,fn,newArgs);
}else{
return fn.apply(this,newArgs);
}
}
}

//test curry

function multiFn(a, b, c) {
return a * b * c;
}

var multi = curry(multiFn);
console.log(multi(2)(3)(4)) //24
console.log(multi(2,3,4)); //24
console.log(multi(2)(3,4)); //24
console.log(multi(2,3)(4)); //24

实现一个flat

1
2
3
4
5
6
7
//flat
function _flat(arr){
return [].concat(...arr.map(item => Array.isArray(item) ? _flat(item) : [item]))
}

//test flat
console.log(_flat([1,[2,[3,[4]]]])) //[1,2,3,4]