当前位置:网站首页>This + closure + scope interview question

This + closure + scope interview question

2022-07-05 02:45:00 _ Language and ink

Scope chain

let a = 'global';
    console.log(a);

    function course() {
    
        let b = 'zhaowa';
        console.log(b);

        session();
        function session() {
    
            let c = 'this';
            console.log(c);

            teacher();
            function teacher() {
    
                let d = 'yy';
                console.log(d);

                console.log('test1', b);
            }
        }
    }
    console.log('test2', b);
    course();

Report errors :b is not defined

  if(true) {
    
        let e = 111;
        console.log(e);
    }
    console.log('test3', e)

Report errors : e is not defined

  • For the scope chain, we directly locate the scope chain by creating the state
  • Manually cancel global , Use block level scope

this - Context context

this It is determined by the dynamic reading context during execution , Instead of creating

The function is called directly this Pointing to window( Function expression 、 Anonymous functions 、 Nested function )

function foo(){
    
console.log(this)   // Point to window
}

Implicit binding

1.this Point to the upper level of the call stack => object 、 Array and other reference logic

   function fn() {
    
        console.log(' Implicit binding ', this.a);
    }
    const obj = {
    
        a: 1,
        fn
    }

    obj.fn = fn;
    obj.fn();

Interview questions :

  const foo = {
    
        bar: 10,
        fn: function() {
    
            console.log(this.bar);
            console.log(this);
        }
    }

    let fn1 = foo.fn;

    fn1();  //this  Point to windows

    //  Questioning 1,  How to change the direction 
    const o1 = {
    
        text: 'o1',
        fn: function() {
    
            //  Use context directly  -  Traditional living 
            return this.text;
        }
    }

    const o2 = {
    
        text: 'o2',
        fn: function() {
    
            //  Call the executive  -  Department collaboration 
            return o1.fn();
        }
    }

    const o3 = {
    
        text: 'o3',
        fn: function() {
    
            //  Direct internal structure  -  Public person 
            let fn = o1.fn;
            return fn();
        }
    }

    console.log('o1fn', o1.fn());
    console.log('o2fn', o2.fn());
    console.log('o3fn', o3.fn());

	o1fn o1
    o2fn o1
    o3fn undefined   // Point to windows
  • When executing a function , The function is called by the upper level , The context points up one level
  • or Directly become a public function , Point to window
    Questioning : Now I want to console.log(‘o2fn’, o2.fn()); The result is o2
    // 1.  Artificial interference , change this - bind/call/apply
    // 2.  Don't change this
    const o1 = {
    
        text: 'o1',
        fn: function() {
    
            return this.text;
        }
    }

    const o2 = {
    
        text: 'o2',
        fn: o1.fn
    }

    console.log('o2fn', o2.fn());
    // this Point to the object he called last. , Put in fn Execution time ,o1.fn Grab it and mount it on yourself o2fn You can go up. 

2.new - this Pointing to new Examples obtained later

  class Course {
    
        constructor(name) {
    
            this.name = name;
            console.log(' In the constructor this:', this);
        }

        test() {
    
            console.log(' Class methods this:', this);
        }
    }

    const course = new Course('this');
    course.test();
    // Point to example course

Questioning : Asynchronous methods in class ,this Is there a difference

 class Course {
    
        constructor(name) {
    
            this.name = name;
            console.log(' In the constructor this:', this);
        }

        test() {
    
            console.log(' Class methods this:', this);
        }
        asyncTest() {
    
            console.log(' Outside the asynchronous method :', this);
            setTimeout(function() {
    
                console.log(' In asynchronous methods :', this);
            }, 100)
        }
    }

    const course = new Course('this');
    course.test();
    course.asyncTest();

 Insert picture description here

  • perform settimeout when , Anonymous method execution , The effect is the same as that of global execution
  • Questioning How to solve : Use the arrow function

Explicitly bound (bind|apply|call)

  function foo() {
    
        console.log(' Internal function this', this);
    }
    foo();

    //  Use 
    foo.call({
    a: 1});
    foo.apply({
    a: 1});

    const bindFoo = foo.bind({
    a: 1});
    bindFoo();

Questioning :call、apply、bind The difference between

  • call 、apply It's not the same One by one / Array passed in
  • bind Return function directly , Need to execute again Biography and reference call equally

bind Principle / Handwriting bind

Principles or handwritten topics , Their thinking :
1. Explain the principle , Write notes
2. According to the notes , Supplement the source code

 function sum(a, b, c) {
    
        console.log('sum', this);
        return a + b + c;
    }
    // 1.  demand : Handwriting bind => bind Location ( Hang there ) => Function.prototype
    Function.prototype.newBind = function() {
    
        // 2. bind What is it? ? 
        const _this = this;
        const args = Array.prototype.slice.call(arguments);
        // args characteristic , The first is new this, The second item ~ The last function passes parameters 
        const newThis = args.shift();

        // a.  Returns a function 
        return function() {
    
            // b.  Return the execution result of the original function  c.  The transmission parameters remain unchanged 
            return _this.apply(newThis, args);
        }
    }


    // Handwriting apply
    Function.prototype.newApply = function(context) {
    
        //  edge detection 
        //  Function detection 
        if (typeof this !== 'function') {
    
            throw new TypeError('Error');
        }
        //  Parameter detection 
        context = context || window;

        //  Mount the execution function 
        context.fn = this;

        //  Execute function 
        let result = arguments[1]
            ? context.fn(...arguments[1])
            : context.fn();

        //  Destroy temporary mount 
        delete context.fn;
        return result;
    }

How to break through the constraints of scope ?

Closure

Closure : A combination of a function and references to its surrounding states

  function mail() {
    
        let content = ' Letter ';
        return function() {
    
            console.log(content);
        }
    }
    const envelop = mail();
    envelop();
  • The variable value within the scope of the function is obtained outside the function
    When a function is used as an argument
   //  Single responsibility 
    let content;
    //  Universal storage 
    function envelop(fn) {
    
        content = 1;

        fn();
    }

    //  Business logic 
    function mail() {
    
        console.log(content);
    }

    envelop(mail);
    

 Insert picture description here
Nested function

  let counter = 0;

    function outerFn() {
    
        function innerFn() {
    
            counter++;
            console.log(counter);
            // ...
        }
        return innerFn;
    }
    outerFn()();

 Insert picture description here
Event handling ( Asynchronous execution ) The closure of

 let lis = document.getElementsByTagName('li');

    for(var i = 0; i < lis.length; i++) {
    
        (function(i) {
    
            lis[i].onclick = function() {
    
                console.log(i);
            }
        })(i);
    }

solve :
1. Execute function immediately instead , The form of transmitting reference .
2. take var Change it to let
Questioning :
Perform nesting now

 (function immediateA(a) {
    
        return (function immediateB(b) {
    
            console.log(a); // 0
        })(1);
    })(0);

The immediate execution of a function encounters a block level scope

  let count = 0;

    (function immediate() {
    
        if(count === 0) {
    
            let count = 1;

            console.log(count);
        }
        console.log(count);
    })();

 Insert picture description here
Split execution - Focus on

  function createIncrement() {
    
        let count = 0;
        
        function increment() {
    
            count++;
        }

        let message = `count is ${
      count}`;

        function log() {
    
            console.log(message);
        }

        return [increment, log];
    }
    const [increment, log] = createIncrement();

    increment();
    increment();
    increment();
    log();

Implement private variables

   function createStack() {
    
        return {
    
            items: [],
            push(item) {
    
                this.item.push(item);
            }
        }
    }

    const stack = {
    
        items: [],
        push: function() {
    }
    }

    function createStack() {
    
        const items = [];
        return {
    
            push(item) {
    
                items.push(item);
            }
        }
    }
    // Vuex store
原网站

版权声明
本文为[_ Language and ink]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/186/202207050240462161.html