[Step-By-Step] Weekly Question & & Answer Summary/01

  Front end, javascript, node.js, Programmer

About [Step-By-Step]

If you don’t take too many steps, you’ll reach a thousand miles.

Step-By-Step(Click to enter the project) It was me at2019-05-20The beginning of a project, the project vision: one step at a time, quantitative change leads to qualitative change.

Step-By-StepOnly face-to-face questions will be issued on weekdays, mainly considering that some of the small partners are usually busy at work or have travel plans on weekends. Every weekend, I will read your answers carefully and sort out the best one. Because of my limited level, I will correct any mistakes in time. The small partners participating in the answer can compare their answers.

The answer is not an end in itself., don’t want everyone to just simply search for the answer, copy and paste it under issue. More importantly, I hope everyone can find out and fill the vacancy/consolidate the relevant knowledge in time.

More quality articles to stamp on: https://github.com/YvetteLau/ …

1. How to correctly judge the direction of this? (2019-05-20)

If you use one sentence to explain the direction of this, that is, whoever calls it, this points to whom.

However, through this sentence alone, we often cannot accurately judge the direction of this. Therefore, we need to use some rules to help ourselves:

The direction of this can be judged in the following order:

1. this in the Global Environment

Browser environment: whether in strict mode or not, this points to global objects in the global execution environment (outside any function body)window;

Node Environment: this is an empty object in the global execution environment (outside any function body) regardless of whether it is in strict mode or not.{};

2. Is itnewBinding

If it isnewBinding, and no function or object is returned in the constructor, this points to this new object. As follows:

The constructor return value is not function or object.

function Super(age) {
    this.age = age;
}

let instance = new Super('26');
console.log(instance.age); //26

The return value of the constructor is function or object, in which case this refers to the returned object.

function Super(age) {
    this.age = age;
    let obj = {a: '2'};
    return obj;
}


let instance = new Super('hello');
console.log(instance.age); //undefined

You can wonder why this is happening. Let’s take a looknewThe implementation principle of:

  1. Create a new object.
  2. This new object will be executed[[prototype]]Connection.
  3. Attributes and methods are added to the object referenced by this. The method in the constructor is executed.
  4. If the function does not return another object, this points to the new object, otherwise this points to the object returned in the constructor.
function new(func) {
    let target = {};
    target.__proto__ = func.prototype;
    let res = func.call(target);
    //排除 null 的情况
    if (res && typeof(res) == "object" || typeof(res) == "function") {
        return res;
    }
    return target;
}

3. Whether the function is called through call,apply, or bind binding is used. If so, this binding is the specified object [boils down to explicit binding].

function info(){
    console.log(this.age);
}
var person = {
    age: 20,
    info
}
var age = 28;
var info = person.info;
info.call(person);   //20
info.apply(person);  //20
info.bind(person)(); //20

Here also need to pay attention to aSpecialCase, if the first parameter value passed in by call,apply, or bind isundefinedOr ..null, the value of this in strict mode is the passed-in value null /undefined. In non-strict mode, this refers to the global object (the node environment is global and the browser environment is window) as the default binding rule applied in practice.

function info(){
    //node环境中:非严格模式 global,严格模式为null
    //浏览器环境中:非严格模式 window,严格模式为null
    console.log(this);
    console.log(this.age);
}
var person = {
    age: 20,
    info
}
var age = 28;
var info = person.info;
//严格模式抛出错误;
//非严格模式,node下输出undefined(因为全局的age不会挂在 global 上)
//非严格模式。浏览器环境下输出 28(因为全局的age会挂在 window 上)
info.call(null);

4. Implicit binding, the function call is triggered on an object, that is, there is a context object at the call location. Typical implicit calls are:xxx.fn()

function info(){
    console.log(this.age);
}
var person = {
    age: 20,
    info
}
var age = 28;
person.info(); //20;执行的是隐式绑定

5. Default binding, the default rule used when other binding rules cannot be applied, usually an independent function call.

Non-strict mode: node environment, execute global object global, browser environment, execute global object window.

Strict mode: execute undefined

function info(){
    console.log(this.age);
}
var age = 28;
//严格模式;抛错
//非严格模式,node下输出 undefined(因为全局的age不会挂在 global 上)
//非严格模式。浏览器环境下输出 28(因为全局的age不会挂在 window 上)
//严格模式抛出,因为 this 此时是 undefined
info(); 

6. The situation of arrow function:

The arrow function does not have its own this, which inherits this bound by the outer context.

let obj = {
    age: 20,
    info: function() {
        return () => {
            console.log(this.age); //this继承的是外层上下文绑定的this
        }
    }
}

let person = {age: 28};
let info = obj.info();
info(); //20

let info2 = obj.info.call(person);
info2(); //28

Click to view more

2. What are the original types in 2.JS? Is null an object? What is the difference between the original data type and the complex data type? (2019-05-21)

At present, there are six original types of JS, namely:

  • Boolean
  • String
  • Number
  • Undefined
  • Null
  • Symbol(ES6 New)

ES10 has added a new basic data type: BigInt

There is only one complex data type: Object

Null is not an object, althoughtypeof nullThe output isobjectThis is a problem left over from history. The original version of JS used a 32-bit system. For performance reasons, the type information of low-order storage variables is used. The beginning of 000 represents an object.nullIt is expressed as all zeros, so it is wrongly judged asobject.

The difference between basic data types and complex data types is:

  1. Memory allocation is different
  • The basic data types are stored in the stack.
  • Complex data types are stored in the heap, and variables stored in the stack point to reference addresses in the heap.
  1. Access mechanisms are different
  • The basic data type is accessed by value
  • Complex data types are accessed by reference. JS does not allow direct access to objects stored in heap memory. When accessing an object, the address of the object in heap memory is obtained first, and then the value of the object is obtained according to the address.
  1. Different when copying variables (a=b)
  • Basic data type: a=b; A copy of the original value stored in B is assigned to the new variable A, A and B are completely independent and do not affect each other.
  • Complex data type: a=b; Assigning the reference address of the object memory saved by b to the new variable a; A and B point to the same heap memory address. One value changes and the other changes.
let b = {
    age: 10
}

let a = b;
a.age = 20;
console.log(a); //{ age: 20 }
  1. The difference of parameter passing (argument/formal parameter)

Function parameters are passed by value (contents stored in stack): basic data type, copied value; Complex data type, copy the reference address

//基本数据类型
let b = 10

function change(info) {
    info=20;
}
//info=b;基本数据类型,拷贝的是值得副本,二者互不干扰
change(b);
console.log(b);//10
//复杂数据类型
let b = {
    age: 10
}

function change(info) {
    info.age = 20;
}
//info=b;根据第三条差异,可以看出,拷贝的是地址的引用,修改互相影响。
change(b);
console.log(b);//{ age: 20 }

Click to view more

3. Tell me about your understanding of the semantics of HTML5 (2019-05-22)

Semanticization means that, as the name implies, the semanticization of HTML5 refers to the reasonable and correct use of semanticized tags to create page structures, such as header,footer,nav. the function of this tag can be intuitively known from the tags, instead of abusing div.

The advantages of semantics include:

  • The code structure is clear and easy to read, which is beneficial to development and maintenance.
  • It is convenient for other devices to parse (e.g. screen readers) and render web pages according to semantics.
  • Is conducive to search engine optimization (SEO), search engine crawler will give different weights according to different tags

Semantic labels mainly include:

  • Title: Mainly used for information introduction of the header of the page
  • Header: Defines the header of the document
  • Nav: Mainly used for page navigation
  • Main: specifies the main contents of the document. It should be unique to the document. It should not contain content that appears repeatedly in the document, such as sidebars, navigation bars, copyright information, site logos, or search forms.
  • Article: Independent Self-contained Content
  • H1~h6: Define Title
  • Ul: Used to define unordered lists
  • Ol: Used to define an ordered list
  • Address: Defines the contact information of the author/owner of a document or article.
  • Canvas: used to draw images
  • Dialog: Define a dialog box, confirmation box, or window
  • Aside: Define content other than what it is.<aside>The content of can be used as a sidebar for articles.
  • Section: Defines a section in a document. Such as chapters, headers, footers, or other parts of the document.
  • Figure: Specify independent streaming content (images, charts, photos, codes, etc.). The content of the figure element should be related to the main content, but if deleted, it should not affect the document flow.
  • Details: Describes the details of a document or part of a document
  • Mark: Text that means marked.

Semantic application

For example, use these visual tags to build the following page structure:

For early browsers that do not support HTML5, such as IE8 and earlier versions, we can introduce html5shiv to support it.

Click to view more

4. How to make the value of (a == 1 && a == 2 && a == 3) true?

4.1 Using Implicit Conversion Rules

==When the left and right data types of operators are inconsistent, implicit conversion will be performed first.

a == 1 && a == 2 && a == 3The value of means that it cannot be a basic data type. Because if a is null or undefined bool type, it is impossible to return true.

Therefore, it can be inferred that A is a complex data type, and only complex data types in JSobjectRecall what method will be called when Object is converted to the original type?

  • If deployed[Symbol.toPrimitive]Interface, then call this interface, if the return is not the basic data type, throw an error.
  • If not deployed[Symbol.toPrimitive]Interface, then according to the type to be converted, first call thevalueOf/toString

    1. Non-Date type objects,hintYesdefault, the call order is:valueOf>>>toString, i.e.valueOfThe return is not the basic data type, and the call will continue.valueOfIftoStringIf the returned data type is not the basic data type, an error is thrown.
    2. IfhintYesstring(Date object silent person’s hint is string), call order is:toString>>>valueOf, i.e.toStringThe return is not the basic data type, and the call will continue.valueOfIfvalueOfIf the returned data type is not the basic data type, an error is thrown.
    3. IfhintYesnumber, call order is:valueOf>>>toString
var obj = {
    [Symbol.toPrimitive](hint) {
        console.log(hint);
        return 10;
    },
    valueOf() {
        console.log('valueOf');
        return 20;
    },
    toString() {
        console.log('toString');
        return 'hello';
    }
}
console.log(obj + 'yvette'); //default
//如果没有部署 [Symbol.toPrimitive]接口,调用顺序为`valueOf` >>> `toString`
console.log(obj == 'yvette'); //default
//如果没有部署 [Symbol.toPrimitive]接口,调用顺序为`valueOf` >>> `toString`
console.log(obj * 10);//number
//如果没有部署 [Symbol.toPrimitive]接口,调用顺序为`valueOf` >>> `toString`
console.log(Number(obj));//number
//如果没有部署 [Symbol.toPrimitive]接口,调用顺序为`valueOf` >>> `toString`
console.log(String(obj));//string
//如果没有部署 [Symbol.toPrimitive]接口,调用顺序为`toString` >>> `valueOf`

So for this problem, as long as[Symbol.toPrimitive]Interface, the value returned for the first time is 1, and then increment, that is, successfully established.

let a = {
    [Symbol.toPrimitive]: (function(hint) {
            let i = 1;
            //闭包的特性之一:i 不会被回收
            return function() {
                return i++;
            }
    })()
}
console.log(a == 1 && a == 2 && a == 3); //true

callvalueOfSituation of interface:

let a = {
    valueOf: (function() {
        let i = 1;
        //闭包的特性之一:i 不会被回收
        return function() {
            return i++;
        }
    })()
}
console.log(a == 1 && a == 2 && a == 3); //true

In addition, in addition to the I-increasing method, regularization can also be used, as follows

let a = {
    reg: /\d/g,
    valueOf () {
        return this.reg.exec(123)[0]
    }
}
console.log(a == 1 && a == 2 && a == 3); //true

calltoStringInterface, no longer explain.

4.2 Using Data Hijacking

UseObject.definePropertyThe defined property is called when the property is obtainedgetMethods. Using this feature, we arewindowDefinition on objectaProperties, as follows:

let i = 1;
Object.defineProperty(window, 'a', {
    get: function() {
        return i++;
    }
});
console.log(a == 1 && a == 2 && a == 3); //true

ES6 has been addedProxyHere we can also useProxyTo achieve, as follows:

let a = new Proxy({}, {
    i: 1,
    get: function () {
        return () => this.i++;
    }
});
console.log(a == 1 && a == 2 && a == 3); // true

4.3 array oftoStringThe interface calls the of the array by defaultjoinMethod to override the of the arrayjoinMethods.

let a = [1, 2, 3];
a.join = a.shift;
console.log(a == 1 && a == 2 && a == 3); //true

4.4 utilizationwithKeyword

I am personally rightwithAlways stay at a respectful distance from sb. But ..withIndeed, it is also one of the methods of this topic:

let i = 0;

with ({
    get a() {
        return ++i;
    }
}) {
    console.log(a == 1 && a == 2 && a == 3); //true
}

Click to view more

5. What is the function of the debounce function? Please implement an anti-shake function for any application scenarios.

The function of anti-shake function

The function of anti-shake function is to control the number of times the function is executed within a certain period of time. Anti-shake means that the function will only be executed once in n seconds. If it is triggered again in n seconds, the delay time will be recalculated.

For example: Xiao Si is losing weight recently, but she is very greedy. For this reason, it is agreed with his boyfriend that if he does not eat snacks for 10 days, he can buy a bag (don’t ask why it is a bag, because it can cure all kinds of diseases). However, if you eat a snack in the middle, you have to recalculate the time until Xiao Si insists on not eating snacks for 10 days before buying a bag. So, Xiao Si, who can’t keep his mouth shut, didn’t have a chance to buy a bag (sad story) … this is it.Anti shake.

No matter whether you eat snacks or not, you buy a bag every 10 days. If you want to buy a bag in the middle, you have to endure and wait until the 10th day to buy it. This is the case.reduce expenditure. How to control girlfriend’s consumption, ladies and gentlemen, have you got it? Anti-shake is much more effective than throttling!

Anti-shake application scenario

  1. Search box input query, if the user has been in the input, there is no need to constantly call to request the server interface, when the user stops input, call again, set a suitable time interval, effectively reduce the pressure on the server.
  2. Form validation
  3. Button submit event.
  4. Browser window zoom, resize event, etc.

Realization of Anti-shake Function

  1. When the event is triggered for the first time,timerYesnull, callinglater()IfimmediateFortrueThen call immediatelyfunc.apply(this, params); IfimmediateForfalse, thenwaitAfter that, call thefunc.apply(this, params)
  2. When the event is triggered for the second time, iftimerHas been reset tonull(i.e. the countdown to setTimeout ends), then the process is the same as when it was triggered for the first time. iftimerNot fornull(i.e. the countdown to setTimeout has not ended), then clear the timer and start counting again.
function debounce(func, wait, immediate = true) {
    let timer;
    // 延迟执行函数
    const later = (context, args) => setTimeout(() => {
        timer = null;// 倒计时结束
        if (!immediate) {
            func.apply(context, args);
            //执行回调
            context = args = null;
        }
    }, wait);
    let debounced = function (...params) {
        let context = this;
        let args = params;
        if (!timer) {
            timer = later(context, args);
            if (immediate) {
                //立即执行
                func.apply(context, args);
            }
        } else {
            clearTimeout(timer);
            //函数在每个等待时延的结束被调用
            timer = later(context, args);
        }
    }
    debounced.cancel = function () {
        clearTimeout(timer);
        timer = null;
    };
    return debounced;
};

immediateTrue indicates that the function is called at the beginning of each wait delay.

immediateFalse indicates that the function is called at the end of each wait delay.

As long as high-frequency events trigger, the callback function is called at least once.

Click to view more

Reference articles:

[1]https://www.ecma-internationa …

[2]Hey, do you really understand this?

[3]The native JS you must understand during the winter job-hunting season (part one)

[4][Interview] The Native JS You Must Know in Winter Job Hunting Season (Part 2)

[5]https://digcss.com/throttle-t …

Thank you for your friends’ willingness to spend precious time reading this article. If this article gives you some help or inspiration, please don’t be stingy with your praise and Star. Your affirmation is my greatest motivation to move forward.https://github.com/YvetteLau/ …

Recommend to pay attention to my public number:

clipboard.png