Recently I read two volumes of You-Dont-Know-JS. In the process of reading, in order to facilitate future indexing and a deeper understanding, and to avoid forgetting, I have made a summary of the more complicated points in each volume, and edited them as follows.

Blog.xiang. tech/post/js-puz…

types & grammer

  1. Judge the following results

    var s = 'abc';
    s[1] = 'B';
    
    console.log(s);
    
    var l = new String('abc');
    l[1] = 'B';
    console.log(l);
    Copy the code

    Strings and their Boxed objects are immutable and cannot modify in place, so all methods of string return a new string without changing themselves.

    • You-Dont-Know-JS
  2. How to reverse a string?

    s.split('').reverse().join('')

  3. Plug in, why can’t directly use Array. The prototype. Reverse. Call reverse string (s)?

    When an array is reversed, l.everse () changes l itself. As in the first problem, a string cannot change itself.

  4. Determine the following results, why this is the case, and how to make the correct comparison?

    0.1 + 0.2= = =0.3;
    0.8 - 0.6= = =0.2;
    Copy the code

    According to IEEE 754, floating point stores 64 bit double precision, which can represent 2^64 numbers. Floating point is infinite, which means that some floating point numbers must have a loss of precision. 0.1 and 0.2 are represented as binary numbers with a loss of precision. A very small Number is introduced for comparison.EPSILON tolerates error, with a value of 2^-52.

    function equal (a, b) {
      return Math.abs(a - b) < Number.EPSILON
    }
    Copy the code
    • You-Dont-Know-JS
    • zhihu
  5. How do I determine if a value is an integer?

    // ES6
    Number.isInteger(num);
    
    // ES5
    if (!Number.isInteger) {
      Number.isInteger = function(num) {
        return typeof num == "number" && num % 1= =0;
      };
    }
    Copy the code
    • You-Dont-Know-JS#user-content-testing-for-integers
  6. How do you tell if a value is +0?

    function isPosZero (n) {
      return n === 0 && 1 / n === Infinity
    }
    Copy the code
  7. ‘ABC’ is primitive value in ‘ABC’.toupperCase (). How do I access the toUpperCase method

    When the Primitive Value accesses a property or method, it automatically translates to its wrapper object. You can also use Object.prototype.valueof () Unboxing.

    • You-Dont-Know-JS#user-content-boxing-wrappers
  8. Determine the following results (Boxing Wrappers)

    function foo() {
      console.log(this)
    }
    
    foo.call(3);
    Copy the code

    Number (3). The reasons are as above.

  9. Judge the following results

    Array.isArray(Array.prototype)
    Copy the code

    True The prototype of the built-in object is not pure, for example, date. prototype is Date and set. prototype is Set.

    • You-Dont-Know-JS#user-content-native-prototypes
  10. Judge the following results

    Boolean(new Boolean(false));
    Boolean(document.all); [] = =' ';
    [3] = =3; [] = =false;
    42= =true;
    Copy the code

    New Boolean() returns object, true document.all, Falsy value is a value that is forced to be false. Everything else will be converted to true

    • undefined
    • null
    • false
    • +0, -0, and NaN
    • “”

    You-Dont-Know-JS#user-content-toboolean

  11. Identify the following code issues (TDZ)

    var a = 3;
    let a;
    Copy the code

    This is a Temporal Dead Zone problem, you cannot use A until let A is declared.

  12. Identify the following code issues (TDZ)

    var x = 3;
    
    function foo (x=x) {
        // ..
    }
    
    foo()
    Copy the code

    Also, in the function default arguments, there is TDZ.

scope & closures

  1. What does Engine, Scope, and Compiler do in var a = 2

  2. Determine the following results (Lexical Scope)

    var scope = 'global scope';
    function checkScope () {
      var scope = 'local scope';
      function f() {
        return scope; 
      }
      return f;
    }
    
    checkScope()();
    Copy the code

    ‘local scope’

    Since JS is a Lexical Scope, a variable is accessed in the current Scope first and, if not, in the nested Scope until it is found. If not, ReferenceError is reported.

  3. Judge the following results (as follows)

    console.log(a);
    var a = 3;
    Copy the code

    undefined

    The above code is interpreted by the compiler as

    var a;
    console.log(a);
    a = 3;
    Copy the code
  4. Judge the following results (Function First)

    var foo = 1;
    function foo () {}console.log(foo);
    Copy the code

    1. Functions are also promoted, so they are overridden by assignments.

  5. Judge the following results (IIFE & Function First)

    var foo = 1;
    (function () {
      foo = 2;
      function foo () {}
    
      console.log(foo); }) ()console.log(foo);
    Copy the code

    2, 1

    The above code is interpreted by the compiler as follows

    var foo = 1;
    (function () {
      var foo;
      function foo () {
      }
    
      foo = 2;
      console.log(foo); }) ()console.log(foo);
    Copy the code
  6. Determine the following results and how to output in order (Closure)

    for (var i = 0; i < 10; i++) {
      setTimeout(function () {
        console.log(i);
      }, 1000)}Copy the code

    After about 1s, output 10 10s in a row. Since there is no block-level scope, you can either change var to let or wrap setTimeout with a layer of IIFE.

this & object prototypes

Note: the following are in a browser environment

  1. Determine the following results (Default Binding)

    function foo() {
      "use strict";
      console.log( this.a );
    }
    
    var a = 2;
    
    foo();
    Copy the code

    An error is reported, in strict mode of the function, where this is bound to undefined by default.

  2. Judge the following results

    "use strict";
    var a = 2;
    let b = 3;
    
    console.log(this.a, this.b);
    Copy the code

    2, undefined

    In the browser environment, this points to the window, and the variable declared by var is attached to the window. Variables declared by the let do not hang on the window.

  3. Determine the following result (Strict Mode & Default Binding)

    function foo() {
      console.log( this.a );
    }
    
    var a = 2;
    
    (function(){
      "use strict"; foo(); }) ();Copy the code

    2

    The only function that sets strict mode is this, which is undefined. So it will output normally.

  4. Determine the following results (Hard Binding)

    function foo () {
      console.log(this.a);
    }
    
    const o1 = { a: 3 };
    const o2 = { a: 4 };
    
    foo.bind(o1).bind(o2)();
    Copy the code

    3

    Bind is a hard binding. This cannot be bound again after the first binding.

  5. How to realize the Function. The prototype. The bind and the Function. The prototype. SoftBind

    Bind is a hard bind, and softBind can bind this multiple times. The approximate implementation code is as follows. The second argument to bind presets function arguments, so bind is also a partial function. Bind also needs to consider the case of new. But the following example focuses on the differences between hard and soft binding.

    Function.prototype.fakeBind = function (obj) {
      var self = this;
      return function () { self.call(obj); }}Function.prototype.softBind = function(obj) {
      var self = this;
      return function () {
        self.call(this= = =window? obj : this); }};Copy the code
  6. What happens in the process of new, judge the following results (new)

    function F () {
      this.a = 3;
      return {
        a: 4; }}const f = new F();
    console.log(f.a);
    Copy the code

    4

    The process of new is roughly as follows

    1. Create a new object
    2. This points to the instance and executes the function
    3. If no explicit return is made, the instance is returned by default

    Because the function explicitly returns an object at the end, it prints 4

  7. What are data descriptor and Accessor Descriptor

    Both are defined via Object.defineProperty() and have two public key values

    • Specifies whether this key can be deleted
    • Enumerable specifies whether it can be iterated

    Data descriptors have the following key values

    • Writable Indicates whether the key can be changed
    • value

    The accessor descriptor has the following key values

    • set
    • Get Alternatively, accessor descriptors can be represented as literals
    const obj = {
      get a() {},
      set a(val) {}
    }
    Copy the code

    The internal principle of computed in Vue is GET, and that of watch is SET

  8. How do I access properties of an object? ([[Get]])

    Accessing an object’s properties triggers the [[Get]] operation, which is briefly described below

    1. If yes, check the return value of the interceptor. If no, go to the next step
    2. Check its own properties, if not found proceed to the next step
    3. If it is not found, it looks up the prototype chain; if not, it returns undefined

    The search process is similar to the Scope search for variables, except that the object attribute cannot be found and undefined is returned, while Reference Error is reported when the variable cannot be found.

  9. How to assign an attribute to an object ([[Put]])

    Assigning an attribute to an object triggers the [[Put]] operation, as outlined below

    1. Check whether it is blocked by the Proxy
    2. If the object property is its own property (obj.hasownProperty (‘a’) === true)
      1. If the property is an access descriptor, the setter function is called
      2. If the property is a data descriptor, check whether writable is writable
      3. Normal attribute, direct assignment
    3. If the object property exists on the stereotype chain
      1. If the property is an access descriptor, the setter function is called
      2. If the property is a data descriptor, check whether writable is writable. If writable, overridden by its own attribute, otherwise an error is reported in strict mode
      3. Common attributes overridden by their own attributes
    4. If the object does not exist on the prototype chain, assign a value to its property directly
  10. How to traverse an object (? iterator)

    Set the Symbol. Iterator property to the object

  11. How to Implement an inheritance (Object.create & Call)

    In the ES6 era, it’s easy to implement inheritance through class & extends. In the ES5 era, we use the following method

    function A () {}
    
    function B () {
      A.call(this)
    }
    
    B.prototype = Object.create(A.prototype)
    // b.protoType = new A() not recommended
    Copy the code
  12. How to implement Object.create

    As for why new is not recommended for inheritance, the reason is that you can hardly guarantee that A is A pure function, for example, it will have its own attributes, it may manipulate the DOM, etc. Here is a simple version of the implementation, omitting the second argument.

    Object.create = function (o) {
      function F() {}
      F.prototype = o;
      return new F();
    }
    Copy the code

Pay attention to the public number shanyuexixing, record my technical growth, welcome to exchange