1.The call to realize
1. Call changes this direction
2. Pass the parameters analytically
var foo = {
value: 1
};
var value = 2;
function bar() {
console.log(this.value);
}
// bar._call(foo);
Copy the code
In this case console.log will print out 1. That means foo has a bar method executed.
var foo = {
value: 1.bar: bar()
};
Copy the code
How to write?
bar._call(foo, 'aa'.'bb');
Function.prototype._call = function () {
// The incoming value is parsed first
// Change this to the call function foo
// foo adds a new property called bar
ctx = arguments[0] | |window;
ctx.fn = this;
ctx.fn();
delete ctx.fn;
};
Function.prototype._call2 = function (ctx, ... args) {
// The incoming value is parsed first
// Change this to the call function foo
// foo adds a new property called bar
var fn = Symbol(a); ctx = ctx ||window;
ctx[fn] = this;
letresult = ctx[fn](... args);delete ctx[fn];
return result;
};
Copy the code
2. The realization of the apply
Unlike the Call implementation, the arguments passed by Apply are an array
Function.prototype._apply = function (ctx, arr) {
var ctx = ctx || window;
var fn = Symbol(a); ctx[fn] =this;
var result;
if(! arr) { result = ctx[fn](); }else{ result = ctx[fn](... arr); }delete ctx[fn];
return result;
};
Copy the code
3. The realization of the bind
Multiple bind points to the first bind, this
The bind() method creates a new function. When the new function is called, the first argument to bind() will be this when it runs, and the subsequent sequence of arguments will be passed as its arguments before the arguments passed. (From MDN)Copy the code
1. Return a function
2. You can pass in parameters
Function.prototype._bind = function (context) {
var self = this;
var args = Array.prototype.slice.call(arguments.1);
return function () {
var bindArgs = Array.prototype.slice.call(arguments);
self.apply(context, args.concat(bindArgs));
};
};
/ / the third edition
Function.prototype.bind2 = function (context) {
var self = this;
var args = Array.prototype.slice.call(arguments.1);
var fbound = function () {
var bindArgs = Array.prototype.slice.call(arguments);
// When used as a constructor, this refers to the instance and self refers to the binding function, because 'fbound.prototype = this.prototype; ', has changed fbound.prototype to the prototype of the binding function, where the result is true. When true, this points to the instance.
When used as a normal function, this refers to the window, self refers to the binding function, and the result is false. When the result is false, this refers to the binding context.
self.apply(this instanceof self ? this : context, args.concat(bindArgs));
};
// Change the return function's prototype to the binding function's prototype, and the instance can inherit the function's prototype value
fbound.prototype = Object.create(self.prototype);
return fbound;
};
bind = function (context) {
var self = this;
var args = [].slice.call(arguments.1);
var found = function () {
var bindArgs = [].slice.call(arguments);
self.apply(context, args.concat(bindArgs));
};
};
apply = function (ctx, ... args) {
ctx = ctx || window;
const fn = Symbol(a);// Mount the function to the object
ctx[fn] = this;
// Execute the function
letresult = ctx[fn](... args);delete ctx[fn];
return result;
};
Copy the code
A binding function can also use the new operator to create objects: this behavior is like treating the original function as a constructor. The supplied this value is ignored, and the arguments to the call are supplied to the mock function.Copy the code
4. The new implementation
- Returns a new object,
- Point the prototype of the instance to the prototype of the constructor
- This points to the instance itself
// Pass the constructor as an argument
function New(func) {
// Declare an intermediate object, which is the final instance returned
var res = {};
if(func.prototype ! = =null) {
// Point the instance's prototype to the constructor's prototype
res.__proto__ = func.prototype;
}
// ret is the result of the constructor's execution
// Point this of the constructor to this of the instance object res
const ret = func.apply(res, [].slice.call(arguments.1));
if ((typeof ret === 'object' || typeof ret === 'function') && ret ! = =null) {
return ret;
}
return res;
}
function Person(name, age) {
this.name = name;
this.strength = 60;
this.age = age;
return {
name: name,
time: 80
};
return 'aaa';
}
var student = New(Person, 'tom');
Copy the code
If the constructor returns an object or function, only properties in the returned object can be accessed in the student instance.
If a string is returned, no value is returned
5. Instanceof implementation
function _instanceof(left, right) {
if (typeofleft ! = ='object' || left === null) {
return false;
}
let proto = Object.getPrototypeOf(left);
while (true) {
if (proto === null) return false;
if (proto == right.prototype) return true; proto = proto.prototype; }}Copy the code
6. Promise
class MyPromise {
constructor(executor) {
this.thencallback = undefined;
this.rejectcallback = undefined;
this._value = undefined;
this._status = 'pending';
executor(this._resolve.bind(this), this._reject.bind(this));
}
_resolve(value) {
setTimeout(() = > {
this.thencallback(value);
});
}
_reject(value) {
setTimeout(() = > {
this.rejectcallback(value);
});
}
then(then_cb, onRejected) {
this.thencallback = then_cb;
this.rejectcallback = onRejected;
}
catch(onrejected) {
this.then(null, onrejected); }}Promise.resolve = function (value) {
if (value instanceof Promise) return value;
// If thenable is used
if (value && value.then && isFunction(value.then)) return new Promise(value.then);
return new Promise(resolve= > resolve(value));
};
Promise.reject = function (value) {
return new Promise((null, reject) = > reject(value));
};
Promise.all = function (promises) {
let i = 0;
let returnList = [];
return new Promise((resolve, reject) = > {
for (let i = 0; i < promises.length; i++) {
// If there is an error then all. All also enters reject
promises[i].then(data= > {
procssData(num, data);
}, reject);
}
function procssData(num, data) {
i++;
// The order of the arrays must correspond
returnList[num] = data;
// Return if the number of the token is equal to the length
if(i === promises.length) { resolve(returnList); }}}); };Promise.race = function (promises) {
return new Promise((resolve, reject) = > {
for (let i = 0; i < promises.length; i++) { promises[i].then(resolve, reject); }}); };Copy the code
7. Anti shake and throttle
Image stabilization
Events are executed after a certain period of time, and if they are triggered again within that time, the timer is reset
function debounce(fn, time = 300) {
let timer = null;
return function (. args) {
if (timer) clearTimeout(timer);
timer = setTimeout(() = > {
fn.apply(this, args);
}, time);
};
}
debounce(() = > {
console.log(11);
}, 1000);
Copy the code
The throttle
Events will only be taken off once at a time, like a bus every 10 minutes, for click time
function throttle(fn, time = 1000) {
let last = 0;
return function (. args) {
let now = Date.now();
if (now - last < time) return;
last = now;
fn.apply(this, args);
};
}
Copy the code
Merge optimization
Sometimes a long time of anti – shake will result in no execution at all, and must be executed once in a while
function cover(fn, delay) {
let timer = null;
let last = 0;
return function (. args) {
let now = +new Date(a);if (now - last < delay) {
if (timer) clearTimeout(timer);
timer = setTimeout(() = > {
last = now;
fn.apply(this, args);
}, delay);
} else {
last = now;
fn.apply(this, args);
// Each trigger clears the previous timer and starts executing the new timer
` ``js function deounce(func, wait) { let timer; return function () { let arg = arguments; if (timer) clearTimeout(timer); timer = setTimeout(func.apply(this, arg), wait); }; }Copy the code
8. Deep and shallow copies
Shallow copy
function shallowCopy(obj) {
if (typeofobj ! = ='object') return obj;
let newObj = obj.constructor === Array ? [] : {};
for (key in obj) {
if(obj.hasOwnProperty(key)) { newObj[key] = obj[key]; }}return newObj;
}
/ / copy
Copy the code
9. for in \ for of
The for of loop is used to get the value in a key-value pair, while the for in loop gets the key name
A data structure that deploys the symbol. iterator attribute is considered to have an iterator interface and can use the for of loop.
- Arrays Array, Map, Set, String, arguments objects, and Nodelist objects can all be looping values with for of
10. Array method implementation
map
arr.map((item, index) = > {});
Array.prototype._map = function (fn, context) {
var temp = [];
if (typeof fn == 'function') {
for (let i = 0; i < this.length; i++) {
temp.push(fn.call(context, this[i], i, this)); }}else {
console.log('TypeError' + fn + 'is not a function'); }};Copy the code
reduce
promise
// Simplified version
class Promise {
constructor(executor) {
this.thenCb = null;
this.rejectCb = null;
executor(this._resolve.bind(this), this._reject.bind(this));
}
_resolve(value) {
setTimeout(() = > {
this.thenCb(value);
}, 0);
}
_reject(value) {
setTimeout(() = > {
this.rejectCb(value);
}, 0);
}
then(onResolved, onRejected) {
this.thenCb = onResolved;
this.rejectCb = onRejected;
}
catch(onRejected) {
this.then(null, onRejected); }}Copy the code