【JS】提升-相关笔记

168 阅读3分钟

1、call/apply/bind

call、apply、bind用户改变函数执行上下文中的this值的函数。在执行函数的时候,如果要保证函数内部this不被污染或者说需要使函数内部this指向到指定对象的时候

描述

  • call:第一个参数是this的值,后面参数是要传递给函数的参数
  • apply:与call类似,但第二个参数是一个数组,包含了传递给函数的参数
  • bind:返回一个新函数,这个新函数的this值被绑定到bind的第一个函数,并且bind的第二个及之后的参数将作为新函数的默认参数。bind不会立即执行而是返回新函数可被后面调用

区别

  • 立即执行:call和apply是立即执行的
  • 参数传递:call的参数是单独传递的,apply参数是通过数组传递,bind可以接受多个参数(这些参数在bind调用时被固定下来,在新函数被调用时使用)
  • 用途:call和apply通常用于调用对象的方法,而bind则用于创建具有特定this值的函数便于后面调用
  • 最大的区别就是:bind不会被立即调用,而是返回一个函数,函数内部的this指向与bind执行时的第一个参数,而传入bind的第二个及以后的参数作为原函数的参数来调用原函数。

例子

let obj = {
  name: 'Judian',
  fn: function(a,b,c) {
    console.log(this.name,a,b,c)
  }
}
window.name = 'haha'
let nfn = obj.fn.bind(window,1)
nfn(2,3)
// 输出:haha,1,2,3

bind方法将obj.fn的this绑定到window对象并传递了第一个参数1,然后返回的新函数nfn在被调用时传递了额外的两个参数

应用

  • call:用于需要动态设置this值的情况,如:构造函数
  • apply:用于需要传递多个参数的情况(较多时用数组方便)
  • bind:用于需要预先设置this值并在后续调用的场景,如:在事件处理函数中绑定特定的上下文

2、异步操作Generator 函数

描述

生成器函数generator是es6标准引入的新的数据类型。一个generator看上去像函数,但可以返回多次。

generator函数和普通函数区别有两个:

  • function和函数名之间有一个*号。
  • 函数内部使用了yield表达式

可以把generator函数看作是可以暂停和继续执行的函数。与普通函数不同的是,当generator函数被调用时, 并不会立即执行,而是返回一个Iterator对象,通过这个对象可以逐步遍历Generator函数内部状态,generator函数内部用yield关键字来控制返回值,并可以随时停止和恢复函数的执行。

它返回是一个迭代器对象,需要通过 xx.next 方法来完成代码执行。在调用 generator 函数时,它只是进行实例化工作,它没有让函数体里面的代码执行,需要通过 next 方法来让它执行

跟挤牙膏一样,调一次next 它才执行,且遇到yield就停了,等待下一次next

next 方法调用时,它是有返回值的,它的返回值就是 yield 后面的值或函数的返回值

例子

// 同步代码
function* gen() {
    yield 1
    console.log('A')
 
    yield 2
    console.log('B')
    return 4
}
 
// 定义迭代器对象
const iterator = gen()
 
// 异步代码
console.log(iterator.next()) // 打印为空  next返回 {value:1,done:false}
console.log(iterator.next()) // A next返回 {value:2,done:false}
console.log(iterator.next()) // B next返回 {value:4,done:true}
// 如果函数有return值,最后一个next方法,它的value值为return的值 value:4;如果没有。值为 undefined

应用

异步操作的🌰

function* asyncGen() {
  const data = yield fetch('/api/data').then(r => r.json());
  console.log(data);
}

const gen = asyncGen();
gen.next().value.then(result => gen.next(result));