面试题:JS 中 箭头函数

183 阅读3分钟

this 关键字 :函数运行时自动生成的一个内部对象,只能在函数内部使用,总指向调用他的对象

运行时确定this指向

一旦被绑定, 不可以更改

绑定规则:优先级从高到低

  • new绑定 :
    1. this指向生成的实例对象上;
    2. 如果return一个对象,就指向返回的对象;
    3. 如果返回是null,则指向实例对象
  • 显示绑定: apply,call,bind
  • 隐式绑定 : this 指向上一级对象,而不是最外层
  • 默认绑定 :默认绑定到全局环境上
    • 严格模式下: this是undefined
    • 非严格模式下:this 是全局对象(浏览器是window,node是global)

ES6 中 提供了箭头函数

编译时就可以确定this指向

this指向三种情况:

  1. 全局作用域下定义:this指向全局对象
  2. 普通函数内部 定义箭头函数: 继承外部作用域中的this
  3. 作为回调函数:如settimeout、foreach中等,继承定义时所在的作用域;

不适合的几个场景

  1. 对象的属性建议普通函数写法

对象不构成单独的作用域,所以这里的箭头函数指向全局作用域,期望是指向cat对象的,所以这里应该用普通函数

const cat = {
  lives: 9,
  jumps: () => {
    this.lives--;
  }
}
  1. 动态this的时候,也建议普通写法

this 指向了全局

var button = document.getElementById('press');
button.addEventListener('click', () => {
  this.classList.toggle('on');
});
  1. 原型上添加方法也建议使用普通函数

此时this指向window

Cat.prototype.sayName = () => {
    console.log(this === window) //true
    return this.name
}
const cat = new Cat('mm');
cat.sayName()

箭头函数有几个使用注意点。

  1. 箭头函数没有自己的this对象

  2. 不可以当作构造函数,也就是说,不可以对箭头函数使用new命令,否则会抛出一个错误。

  3. 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

  4. 不可以使用yield命令,因此箭头函数不能用作 Generator 函数。

Generator 函数:

ES6 提供的异步编程解决方案,asycn是他的语法糖,相当于自动执行generator函数;

  • 他用function * 来声明,内部使用yield来暂停;会返回一个遍历器对象; 通过next方法遍历到下一个内部状态;done可以用来判断是否有下一个状态;

  • for of 可以遍历 具有迭代器的对象,所以可以遍历generator函数

区别就是 generator不是为了异步而设计的,promise和async 是专门为了处理异步操作的;

面试题:

  1. 箭头函数为什么不能用作构造函数:因为没有自己的this

new 一个函数 是创建构造函数的形式,会经过4个步骤:1.创建一个空对象,2.将对象和构造函数通过原型链链接起来 3. 改变this指向为实例对象 4. 判断构造函数的返回值是否是对象,是对象 返回 返回的对象;

function myNew(fn, ...args){
    var obj = {};
    obj.__proto__ = fn.prototype;
    let result  = fn.apply(obj,args);
    return result instanceof Object ? result : obj
}
  1. 箭头函数内可以使用arguments?

不可以,获取参数可以通过...args 的形式

  1. 箭头函数可以作为generator函数吗?

不可以, 因为内部不能使用yeild

  1. 箭头函数的this指向

在编译时候就确定,继承外层作用域的this; 如果箭头函数定义在全局,那么就指向全局对象