preface

It doesn’t matter whether it’s winter or mild winter, you need to be well prepared for the job interview. This article is a summary of the handwritten questions I prepared for the recent job hunting and the written interview. For myself, and for those who need it.

Handwritten questions are better prepared for a link, most of the companies to examine the question is also so much, mostly not beyond the scope.

This is the second article in a series of handwriting questions.


To:

  1. Summary of three years’ experience in “Winter” front-end interview (including Toutiao, Baidu, Ele. me, Didi, etc.)
  2. “Winter” three years of experience in the front end of the interview summary (including toutiao, Baidu, Ele. me, Didi, etc.) CSS
  3. Summary of the three years’ experience in the front-end interview of “Winter” (including Toutiao, Baidu, Ele. me, Didi, etc.)
  4. “Winter” three years of experience front-end interview summary (including toutiao, Baidu, Ele. me, Didi, etc.) handwritten question (promise)

Implement eventEmitter

The observer pattern is a design pattern that we often come across in our work. This design pattern should be familiar to anyone who has used jquery. EventEmitter is the core of Node, and the main methods include on, EMIT, off, and once.

class EventEmitter {
    constructor(){
        this.events = {}
    }
    on(name,cb){
        if(! this.events[name]){ this.events[name] = [cb]; }else{ this.events[name].push(cb) } } emit(name,... arg){if(this.events[name]){ this.events[name].forEach(fn => { fn.call(this,... arg) }) } } off(name,cb){if(this.events[name]){
            this.events[name] = this.events[name].filter(fn => {
                returnfn ! = cb }) } } once(name,fn){ var onlyOnce = () => { fn.apply(this,arguments); this.off(name,onlyOnce) } this.on(name,onlyOnce);returnthis; }}Copy the code

Implementation inheritance

Inheritance is an invariable examination point. From ES5 to ES6, there are many inheritance methods. Articles on inheritance usually start with the basic Prototype chain inheritance, call inheritance that borrows from the superclass constructor, and a combination of the two. This article only provides the ultimate method, if you want to learn about other methods, you can do your own search.

// ES5
function Parent(name,age){
    this.name = name;
    this.age = age;
}
Parent.prototype.say = function(){
    console.log('I am' + this.name)
}

function Child(name, age, sex){
    Parent.call(this,name,age);
    this.sex = sex;
}

Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

Copy the code
// ES6 class Parent { constructor(name,age){ this.name = name; this.age = age; } } class Child extends Parents{ constructor(name,age,sex){ super(name,age); this.sex = sex; // You must call super to use this}}.Copy the code

Implement instanceof

The instanceof operator is used to check whether the constructor’s Prototype property is present on the prototype chain of an instance object. But it’s also about inheritance.

function myInstanceof(left,right){
    var proto = left.__proto__;
    var protoType = right.prototype;
    while(true) {if(proto === null){
            return false
        }
        if(proto == protoType){
            return true
        }
        proto = proto.__proto__
    }
}
Copy the code

The process of new

When we new an object, what exactly do we do? The instructions given on MDN are as follows:

  1. Create an empty simpleJavaScriptObject (that is {});
  2. Link this object (that is, set its constructor) to another object;
  3. Take the object created in Step 1 as the objectthisContext;
  4. Returns if the function does not return an objectthis.

Var child = new Parent()

function newParent(){ var obj = {}; // create an object obj.__proto__ = Parent. Prototype; // Then point the object's __proto__ attribute to the constructor's protoType var result = parent.call (obj) // Execute the constructor's method, passing obj as thisreturn typeof(result) == 'object' ?  result : obj
}
Copy the code

lazyMan

The original question is as follows:

To implement a LazyMan, call LazyMan("Hank") Output: Hi! This is Hank! LazyMan ("Hank").sleep(10).eat("dinner"Output) Hi! This is Hank! // Wait 10 seconds.. Wake up after 10 Eat dinner~ LazyMan("Hank").eat("dinner").eat("supper"Hi This is Hank! Eat dinner~ Eat supper~ LazyMan("Hank").sleepFirst(5).eat("supper"// Wait 5 seconds Wake up after 5 Hi This is Hank! Eat supper and so on.Copy the code

This problem mainly examines the chain call, task queue, flow control, etc. The key is to call the next event manually by calling the next function, similar to the execution of Express middleware and Vue-Router routing.

  function _LazyMan(name){
    this.nama = name;
    this.queue = [];
    this.queue.push(() => {
        console.log("Hi! This is " + name + "!");
        this.next();
    })
    setTimeout(()=>{
        this.next()
    },0)
  }
  
  _LazyMan.prototype.eat = function(name){
    this.queue.push(() =>{
        console.log("Eat " + name + "~");
        this.next()
    })
    return this;
  }

  _LazyMan.prototype.next = function(){
    var fn = this.queue.shift();
    fn && fn();
  }

  _LazyMan.prototype.sleep = function(time){
    this.queue.push(() =>{
        setTimeout(() => {
            console.log("Wake up after " + time + "s!");
            this.next()
        },time * 1000)
    })
    return this;
  }

  _LazyMan.prototype.sleepFirst = function(time){
    this.queue.unshift(() =>{
        setTimeout(() => {
            console.log("Wake up after " + time + "s!");
            this.next()
        },time * 1000)
    })
    return this;
  }

  function LazyMan(name){
    return new _LazyMan(name)
  }

Copy the code

To realize the json

Jsonp is cross-domain. The principle is to achieve cross-domain implementation by dynamically inserting script tags, because script scripts are not restricted by the same origin policy. It consists of two parts: a callback function and data. For example:

 function handleResponse(response){
    alert("You're at IP address" + response.ip + ", which is in " +response.city + "," + response.region_name);    
    }
    var script = document.createElement("script");
    script.src = "http://freegeoip.net/json/?callback=handleResponse";
    document.body.insertBefore(script,document.body.firstChild);    
}
Copy the code

Based on the above example, let’s implement a generic JSONP function

function jsonp(obj) {
    const {url,data} = obj;
    if(! url)return
    return new Promise((resolve, reject) => {
        const cbFn = `jsonp_${Date.now()}` 
        data.callback = cbFn
        const head = document.querySelector('head')
        const script = document.createElement('script')
        const src = `${url}?${data2Url(data)}`
        console.log('scr',src)
        script.src = src
        head.appendChild(script)
        
        window[cbFn] = function(res) {
            res ? resolve(res) : reject('error')
            head.removeChild(script)
            window[cbFn] = null 
        }
    })
}

function data2Url(data) {
    return Object.keys(data).reduce((acc, cur) => {
        acc.push(`${cur}=${data[cur]}`)
        return acc
    }, []).join('&')
}
// jsonp({url:'www.xxx.com',data:{a:1,b:2}})
Copy the code

Function currying

Function corrification is the technique of converting a function that takes multiple arguments into a function that takes a single argument (the first argument of the original function) and returns a new function that takes the remaining arguments and returns the result. It is a use of higher-order functions. For example, the summation function add(1,2,3), which currie transforms into Add (1), (2), (3)

functioncurrying(fn,... args){if(fn.length <= args.length){
        returnfn(... args) }return function(... args1){returncurrying(fn,... args,... args1) } }function add(a,b,c){
    returnA + b + c} add(1,2,3); curryingAdd(1)(2)(3) // 6Copy the code

Write in the last

There are mistakes also please friends timely pointed out, so as not to mistake people’s children. To see the content, turn to the link ~ at the top of the page