La cadena de alcance/esto apunta a preguntas comunes de la entrevista

cadena de alcance

  1. Cadena de alcance: determinada por el estado de creación
  2. Cancelación manual del alcance global: a través del alcance a nivel de bloque
let a = 'global'
console.log(a);//'global'
function course() {
  let b = 'this指向'
  console.log(b);//'this指向'

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

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

      console.log('test1', b);//'test1' 'this指向'
    }
  }
}

console.log('test2', b)//b is not defined
course()

La función se llama directamente: esto apunta a la ventana

function foo() {
  console.log('函数内部的this', this);//window
}
foo()

Enlace implícito: esto apunta al nivel anterior

function fn() {
  console.log('隐式绑定', this); // obj
}
const obj = {
  a: 1,
}
obj.fn = fn
obj.fn()

Preguntas de entrevista:

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

// 取出
let fn1 = foo.fn
// 执行
fn1()

const o1 = {
  text: 'o1',
  fn: function () {
    return this.text
  }
}
const o2 = {
  text: 'o2',
  fn: function () {
    return o1.fn()
  }
}
const o3 = {
  text: 'o3',
  fn: function () {
    let fn = o1.fn
    return fn()
  }
}

console.log('01fn', o1.fn());//o1
console.log('02fn', o2.fn());//o1
console.log('03fn', o3.fn());//undefined ( 因为 this 指向 window )

Seguimiento: cómo cambiar esto a punto: ahora el resultado de console.log('o2fn', o2.fn()) es o2

const o1 = {
  text: 'o1',
  fn: function () {
    return this.text
  }
}
const o2 = {
  text: 'o2',
  fn: o1.fn
}

console.log('01fn', o1.fn());//o1
console.log('02fn', o2.fn());//o2

new: esto apunta a la instancia obtenida después de new

class Course {
  constructor(name) {
    this.name = name
    console.log('构造函数内的this', this); // course
  }
  test() {
    console.log('类方法中的this', this); // course
  }
}

const course = new Course('yy')
course.test()

Seguimiento: ¿Hay alguna diferencia entre este puntero en métodos sincrónicos y asincrónicos en una clase?

class Course {
  constructor(name) {
    this.name = name
    console.log('构造函数内的this', this);//course
  }
  test() {
    console.log('类方法中的this', this);//course
  }
  asyncTest() {
    console.log('异步方法外的this', this);//course
    // 普通函数
    setTimeout(function () {
      console.log('异步方法内的this1', this);//window
    }, 100);
    // 箭头函数
    setTimeout(() => {
      console.log('异步方法内的this2', this);//course
    }, 200);
  }
}

const course = new Course('yy')
course.test()
course.asyncTest()

Cómo romper los grilletes del alcance: cierres

  • Escenarios de aplicación de cierres

  1. Función como valor de retorno: se puede acceder a las variables dentro de la función fuera de la función
    function mail() {
      let content = '信'
      return function () {
        console.log(content);
      }
    }
    const envelop = mail()
    envelop()
  2. funcionar como parámetro
    let content
    function envelop(fn) {
      content = 1
      fn()
    }
    
    function mail() {
      console.log(content);
    }
    envelop(mail)
  3. Anidamiento de funciones: aplicación de contadores
    let count = 0
    function outerFn() {
      function innerFn() {
        count++
        console.log(count);
      }
      return innerFn
    }
    outerFn()()
  4. manejo de eventos (asincrónico)
    let lis = document.querySelector('li')
    for (let i = 0; i < lis.length; i++) {
      (function (i) {
        lis[i].onclick = function () {
          console.log(i);
        }
      })(i)
    }
  • Seguir:
  1. Ejecutar anidamiento inmediatamente
    (function immediateA(a) {
      return (function (b) {
        console.log(a);//0
      })(1)
    })(0)
  2. Cuando una función inmediata encuentra un ámbito de nivel de bloque
    let count = 0;
    (function immediate() {
      if (count === 0) {
        let count = 1
        console.log(count); // 1
      }
      console.log(count); // 0
    })()
  3. ejecución dividida
    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() // count is 0
    function createIncrement() {
      let count = 0
    
      function increment() {
        count++
      }
    
      
      function log() {
        let message = `count is ${count}`
    
        console.log(message);
      }
      return [increment, log]
    }
    
    const [increment, log] = createIncrement()
    
    increment()
    increment()
    increment()
    log() // count is 3
  4. Implementar variables privadas
    function createStack() {
      const items = []
      return {
        push(item){
          items.push(item)
        }
      }
    }
    
    //给外界只暴露一个操作变量items的push方法,会形成对变量的保护

Supongo que te gusta

Origin blog.csdn.net/m0_56274171/article/details/123421334
Recomendado
Clasificación