This binding
- Show binding call, apply, bind
- Call, apply implementation: make this function a property that is passed to this(context) and called through context.fn(), then delete context.fn
Function.prototype.myCall = function (context, ... args) {
let context = context || window;
context.fn = this;
letresult = context.fn(... args);delete context.fn;
return result;
};
Function.prototype.myApply = function (ctx, arr) {
let ctx = ctx || window;
ctx.fn = this;
letres = ctx.fn(... arr);delete ctx.fn;
return res;
};
Copy the code
- Bind implementation: returns a new function that forces the bind to this and inherits the properties of the original function
Function.prototype.myBind = function (ctx, ... args1) {
let self = this;
function fn(. args2) {
return self.call(this instanceof fn ? this: ctx, ... args1, ... args2); } fn.prototype =Object.create(self.prototype);
return fn;
};
Copy the code
- The new binding
- This, the constructor of the new call, points to the new object returned
- The new process:
- Create () creates a new Object that inherits the constructor’s properties
- Displays the binding constructor’s this to the object
- Returns the object returned by the constructor if the constructor returns an object, otherwise the newly created object is returned
function myNew(. args) {
const constructor = args.shift();
const obj = Object.create(constructor.prototype);
const res = constructor.apply(obj, args);
return typeof res === 'object' ? res : obj;
}
Copy the code
- Priority of various bindings
New Binding > Show Binding > Implicit binding
Deep clone & shallow clone
- Shallow clone: Only the first-layer value type can be copied, but not the reference type
function shallowClone(target) {
let cloneTarget = {};
for (const key in target) {
cloneTarget[key] = target[key];
}
return cloneTarget;
}
Copy the code
- Deep clone: Copy multiple layers of objects recursively
function deepClone(target) {
if (typeoftarget ! = ='object') return target;
let cloneTarget = target instanceof Array ? [] : {};
for (const key in target) {
if(target.hasOwnProperty(key)) { cloneTarget[key] = deepClone(target[key]); }}return cloneTarget;
}
Copy the code
- Deep clone update: Stores cloned objects using map, avoiding circular references
function deepClone(target, map = new Map(a)) {
let obj = target instanceof Array ? [] : {};
if (typeoftarget ! = ='object') return target;
if (map.get(target)) {
return map.get(target);
}
map.set(target, obj);
for (let key in Object.keys(target)) {
obj[key] = deepClone(target[key], map);
}
return obj;
}
Copy the code
Js inheritance
The best native inheritance scheme: parasitic combination inheritance
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function () {
console.log(`Hi my name is The ${this.name}. `);
};
function Student(name, grade) {
// Inherit the Person instance attributes
Person.call(this, name);
this.grade = grade;
}
// Inherit the Person prototype method
Object.prototype.create = function (target) {
function F() {}
F.prototype = target.prototype;
return new F();
};
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
Student.prototype.sayGrade = function () {
console.log(`my grade is The ${this.grade}. `);
};
Copy the code
ES6 Inheritance: Class inheritance
- Extends extends the stereotype property of the parent class;
- Call super() to override constructor, inheriting the parent instance properties;
- A call to super.method() overrides a superclass method
class Person {
constructor(name) {
this.name = name;
}
sayHello() {
console.log('hello'); }}class Student extends Person {
constructor(name, age) {
// Inherit the Person instance attributes
super(name);
this.age = age
}
sayBye() {
console.log('bye');
}
// Override the Person prototype method
sayHello() {
super.sayHello();
this.sayBye(); }}Copy the code
Type judgment
Js variable values are classified into primitive types and reference types
- Primitive types: number, string, Boolean, undefined, null, symbol
- Reference types: objects, including Array, Function, Date, etc
Methods for determining types
-
Return ‘object’ for all reference types. Note that typeof null also returns ‘object’.
-
Instanceof: checks whether an Object is an instanceof a class. This can be used to check the reference types Array, Function, null instanceof Object
-
Object. The prototype. ToString. Call () : can be used to determine all the primitive types and reference types, null returns’ [Object null], undefined returns’ [Object undefined] ‘
Instanceof code implementation: recursive loop
function myInstanceOf(instance, Class) {
if (typeofinstance ! = ='object') return false;
if(! instance.__proto__)return false;
if (instance.__proto__ === Class.prototype) return true;
return myInstanceOf(instance.__proto__, Class);
}
Copy the code
The function currization & compose
- Corrification: The function argument is passed in multiple times
fn(a,b,c) === curry(fn)(a)(b)(c)
function curry(fn) {
return function curried(. args1) {
if (args1.length < fn.length) {
// If the parameter is not enough, continue currization
return function (. args2) {
return curried.call(this. args1, ... args2); }; }return fn.call(this. args1); }; }Copy the code
Applications: Redux middleware, HOC
- Compose:
compose(fn1, fn2, fn3)(args) === fn1(fn2(fn3(args)))
Application: Redux middleware
Throttling stabilization
- Throttling:
Only one event callback is fired at regular intervals
// immediate Can be triggered immediately or later
function throttle(fn, wait, immediate) {
let timer;
return function (. args) {
let ctx = this;
if (immediate) {
if(! timer) { fn.call(ctx, ... args); timer =setTimeout(() = > {
timer = null; }, wait); }}else {
if(! timer) { timer =setTimeout(() = >{ fn.call(ctx, ... args); timer =null; }, wait); }}}; }Copy the code
- Stabilization:
Only the last event callback is called within a period of multiple triggered events
Application: Input field multiple inputs only get the final input value
Function debounce(fn, wait, immediate) {let timer; return function (... args) { let ctx = this; clearTimeout(timer); if (immediate) { if (! timer) fn.call(ctx, ... args); timer = setTimeout(() => { timer = null; }, wait); } else { timer = setTimeout(() => { fn.call(ctx, ... args); }, wait); }}; }Copy the code