1. The realization of the call

  • When the first parameter is null or undefined, this refers to the global object Window, and the primitive value refers to the auto-wrapped object of the primitive value, such as String, Number, or Boolean
  • To avoid conflicts between function names and attributes of the context, use the Symbol type as the unique value
  • The function is executed as a context property passed in
  • Delete this property after the function completes execution
  • Return execution result
Function.prototype.myCall = function(context,... args){ let cxt = context || window; Let func = Symbol() CXT [func] = this; let func = Symbol() CXT [func] = this; let func = Symbol() CXT [func] = this; args = args ? Args: [] // Call func in the form of an object call, in which this refers to CXT, which is passed in to bind this to const res = args. Length > 0? cxt[func](... args) : cxt[func](); // delete this method, otherwise it will pollute the incoming object (add this method) delete CXT [func]; return res; }Copy the code

2. The realization of the apply

  • The former part is the same as call
  • The second argument may not be passed, but the type must be array or array-like
Function.prototype.myApply = function(context,args = []){ let cxt = context || window; Let func = Symbol() CXT [func] = this; let func = Symbol() CXT [func] = this; let func = Symbol() CXT [func] = this; // Call func as an object call, in which case this refers to CXT, which is passed in to bind this to const res = args.length > 0? cxt[func](... args) : cxt[func](); delete cxt[func]; return res; }Copy the code

3. The realization of the bind

Need to consider:

  • Bind () can pass multiple arguments in addition to this;
  • New functions created by bind may pass in multiple arguments;
  • New functions may be called as constructors;
  • A function may have a return value;

Implementation method:

  • The bind method does not execute immediately and needs to return a function to be executed; (closures)
  • Implement scope binding (apply)
  • Parameter passing (array passing for apply)
  • When used as a constructor, stereotype inheritance is performed
Function.prototype.myBind = function (context, ... Const fn = this, const fn = this, const fn = this, const fn = this, const fn = this [] args = args? Args: [] // returns a newFn function in which newFn(... newFnArgs) { if (this instanceof newFn) { return new fn(... args, ... newFnArgs) } return fn.apply(context, [...args,...newFnArgs]) } }Copy the code

test

Let name = 'xiaowang ',age =17; Let obj = {name:' xiaozhang ', age: this.age, myFun: Function (from,to){console.log(this.name +' age '+ this.age+' from '+ to ')}} let db = {name: 'd ', age: 99} // result obj. myfun. myCall(db,' chengdu ',' Shanghai '); MyApply (db,[' chengdu ',' Shanghai ']); obj. Myfun. myApply(db,[' Chengdu ',' Shanghai ']); MyBind (db,' chengdu ',' Shanghai ')(); obj. MyBind (db,' Chengdu ',' Shanghai ')(); Obj. MyBind (db,[' chengdu ',' Shanghai '])(); // Dema age 99 from Chengdu, Shanghai to undefinedCopy the code

4. Parasitic combination inheritance

function Person(obj) { this.name = obj.name this.age = obj.age } Person.prototype.add = function(value){ Console. log(value)} var p1 = new Person({name:" tomato ", age: 18}) function Person1(obj) { Person.call(this, Person1. Prototype = object.create (person.prototype); Person1.prototype.constructor = Person1; Person1.prototype. Play = function(value){console.log(value)} var p2 = new Person1({name:" ", age: 118, sex: ""})Copy the code

5. ES6 inheritance

// All methods defined in class are not enumerable. // All methods defined in class are not enumerable. // All methods defined in class are not enumerable. Class People{constructor(name='wang',age='27'){this.name = name; this.age = age; } eat(){console.log(' ${this.name} ${this.age} eat food ')} 'ren',age = '27'){// Super (name, age); Eat (){super.eat()}} let wonmanObj=new Woman('xiaoxiami'); wonmanObj.eat(); // ES5 inherits the instance object of the subclass and then adds the methods of the Parent class to this (parent.apply (this)). // Es6 inheritance uses the keyword super to create an instance object of the parent class, this, and then modify this in the subclass class.Copy the code

6. The new implementation

  • A new object inherited from foo. prototype is created.
  • Call the constructor Foo with the specified arguments and bind this to the newly created object. New Foo is the same as new Foo(), where no argument list is specified and Foo is called without any arguments.
  • The object returned by the constructor is the result of the new expression. If the constructor does not explicitly return an object, the object created in Step 1 is used.
  • In general, constructors do not return values, but the user can choose to actively return objects to override the normal object creation steps
function Ctor(){ .... } function myNew(ctor,... args){ if(typeof ctor ! == 'function'){ throw 'myNew function the first param must be a function'; } var newObj = Object.create(ctor.prototype); Var ctorReturnResult = ctor.apply(newObj, args); // Bind this constructor ctor to newObj var isObject = typeof ctorReturnResult === 'object' && ctorReturnResult! == null; var isFunction = typeof ctorReturnResult === 'function'; if(isObject || isFunction){ return ctorReturnResult; } return newObj; } let c = myNew(Ctor);Copy the code

7. Instanceof implementation

  • Instanceof is an instanceof B used to determine whether A is an instanceof b. the expression A instanceof B returns true if A is an instanceof B, false otherwise.
  • The instanceof operator tests whether an object has a constructor’s Prototype property in its prototype chain.
  • Cannot detect basic data types, results on the prototype chain may not be accurate, cannot detect NULL,undefined
  • Implementation: Iterate through the left variable’s prototype chain until the right variable’s prototype is found. If not, return false
function myInstanceOf(a,b){ let left = a.__proto__; let right = b.prototype; while(true){ if(left == null){ return false } if(left == right){ return true } left = left.__proto__ } } //instanceof The prototype operator is used to determine whether the constructor's prototype property appears anywhere in the object's prototype chain. Function myInstanceof(left, right) {let proto = object.getProtoTypeof (left); While (true) {if (! proto) return false; if (proto === prototype) return true; proto = Object.getPrototypeOf(proto); }}Copy the code

8. The Object. The create () implementation

  • MDN document

  • Object.create() takes the parameter Object as a prototype of a newly created empty Object and returns it

Function myCreate(obj){function C(){}; // Point the function's prototype to obj c.prototype = obj; Return new C()} // Polyfill if (typeof object.create! == "function") { Object.create = function (proto, propertiesObject) { if (typeof proto ! == 'object' && typeof proto ! == 'function') { throw new TypeError('Object prototype may only be an Object: ' + proto); } else if (proto === null) { throw new Error("This browser's implementation of Object.create is a shim and doesn't support 'null' as the first argument."); } if (typeof propertiesObject ! == 'undefined') throw new Error("This browser's implementation of Object.create is a shim and doesn't support a second argument."); function F() {} F.prototype = proto; return new F(); }; }Copy the code

9. The achieve Object. Assign

Object.assign2 = function(target, ... source) { if (target == null) { throw new TypeError('Cannot convert undefined or null to object') } let ret = Object(target) source.forEach(function(obj) { if (obj ! = null) { for (let key in obj) { if (obj.hasOwnProperty(key)) { ret[key] = obj[key] } } } }) return ret }Copy the code

10. The realization of the Promise

Implementing promises requires A full understanding of the Promise A+ specification, but from an overall implementation perspective, there are A few things to consider:

  • Promise is essentially a state machine, and the states can only be the following three: This is a big pity. The change of the state is one-way and can only be realized from Pending -> depressing or Pending -> Rejected. The state change is irreversible
  • Then needs to support chained calls
class Promise { callbacks = []; state = 'pending'; // Add status value = null; Constructor (fn) {fn(this._resolve.bind(this), this._reject. Bind (this)); } then(onFulfilled, onRejected) { return new Promise((resolve, reject) => { this._handle({ onFulfilled: onFulfilled || null, onRejected: onRejected || null, resolve: resolve, reject: reject }); }); } _handle(callback) { if (this.state === 'pending') { this.callbacks.push(callback); return; } let cb = this.state === 'fulfilled' ? callback.onFulfilled : callback.onRejected; if (! This is a big pity. State === 'depressing'? callback.resolve : callback.reject; cb(this.value); return; } let ret = cb(this.value); cb = this.state === 'fulfilled' ? callback.resolve : callback.reject; cb(ret); } _resolve(value) { if (value && (typeof value === 'object' || typeof value === 'function')) { var then = value.then; if (typeof then === 'function') { then.call(value, this._resolve.bind(this), this._reject.bind(this)); return; } } this.state = 'fulfilled'; This. value = value; // save the result this.callbacks. ForEach (callback => this._handle(callback)); } _reject(error) { this.state = 'rejected'; this.value = error; this.callbacks.forEach(callback => this._handle(callback)); }}Copy the code

Promise.resolve

  • Promsie.resolve(value) Can convert any value to value. The state is a fulfilled Promise, but if the value passed in is itself a Promise, it will be returned as is.
Promise.resolve(value) { if (value && value instanceof Promise) { return value; } else if (value && typeof value === 'object' && typeof value.then === 'function') { let then = value.then; return new Promise(resolve => { then(resolve); }); } else if (value) { return new Promise(resolve => resolve(value)); } else { return new Promise(resolve => resolve()); }}Copy the code

Promise.reject

  • Like promise.resolve (), promise.reject () instantiates a Promise in the Rejected state. But unlike promise.resolve (), if you pass a Promise object to promise.reject (), that object becomes the value of the new Promise.
Promise.reject = function(reason) {
    return new Promise((resolve, reject) => reject(reason))
}
Copy the code

Promise.all

  • All Promsie passed in are fulfilled, and a new Promise consisting of their values is returned with the state of fulfilled;
  • As long as one Promise is Rejected, a new Promsie with the Rejected state is returned, and its value is the value of the first Rejected Promise.
  • As long as either Promise is pending, a new Promise in a pending state is returned;
Promise.all = function(promiseArr) { let index = 0, result = [] return new Promise((resolve, reject) => { promiseArr.forEach((p, i) => { Promise.resolve(p).then(val => { index++ result[i] = val if (index === promiseArr.length) { resolve(result) } },  err => { reject(err) }) }) }) }Copy the code

Promise.race

  • Promise.race returns a new instance wrapped with the first Fulfilled or Rejected instance among all iterable instances.
Promise.race = function(promiseArr) {
    return new Promise((resolve, reject) => {
        promiseArr.forEach(p => {
            Promise.resolve(p).then(val => {
                resolve(val)
            }, err => {
                rejecte(err)
            })
        })
    })
}
Copy the code

11. The realization of Ajax

function ajax(url,method,body,headers){
    return new Promise((resolve,reject)=>{
        let req = new XMLHttpRequest();
        req.open(methods,url);
        for(let key in headers){
            req.setRequestHeader(key,headers[key])
        }
        req.onreadystatechange(()=>{
            if(req.readystate == 4){
                if(req.status >= '200' && req.status <= 300){
                    resolve(req.responeText)
                }else{
                    reject(req)
                }
            }
        })
        req.send(body)
    })
}
Copy the code

To summarize

Prepare carefully before the interview. The knowledge points and principles written on the resume should be well prepared. Think about the difficulties and highlights in the project, which is the difference between the interview and others.

There is also to show their modesty and studious, as well as for the future continued to advance the planning, enterprises hire more stable people.

Everything is difficult at the beginning, but programmers this way after a few years of development space is still very large, everything is important to adhere to.

In order to help you better and more efficient preparation for the interview, the electronic draft of “Front-end Engineer Interview Manual” is specially organized.

Front end test summary

JavaScript

performance

linux

Front-end data summary

The full PDF is free to share, just like it,Just click here and get it for free.

The job gap for front-end engineers has been very large, and fewer and fewer people meet the job requirements, so the partners who learn front-end should pay attention to it. They must learn solid skills and do valuable projects, so that no matter what situation they encounter when looking for a job, the problem will not be big.