this 关键字 :函数运行时自动生成的一个内部对象,只能在函数内部使用,总指向调用他的对象
运行时确定this指向
一旦被绑定, 不可以更改
绑定规则:优先级从高到低
- new绑定 :
- this指向生成的实例对象上;
- 如果return一个对象,就指向返回的对象;
- 如果返回是null,则指向实例对象
- 显示绑定: apply,call,bind
- 隐式绑定 : this 指向
上一级对象,而不是最外层- 默认绑定 :默认绑定到全局环境上
- 严格模式下: this是undefined
- 非严格模式下:this 是全局对象(浏览器是window,node是global)
ES6 中 提供了箭头函数
编译时就可以确定this指向
this指向三种情况:
- 全局作用域下定义:this指向全局对象
- 普通函数内部 定义箭头函数: 继承外部作用域中的this
- 作为回调函数:如settimeout、foreach中等,继承定义时所在的作用域;
不适合的几个场景
- 对象的属性建议普通函数写法
对象不构成单独的作用域,所以这里的箭头函数指向全局作用域,期望是指向cat对象的,所以这里应该用普通函数
const cat = {
lives: 9,
jumps: () => {
this.lives--;
}
}
- 动态this的时候,也建议普通写法
this 指向了全局
var button = document.getElementById('press');
button.addEventListener('click', () => {
this.classList.toggle('on');
});
- 原型上添加方法也建议使用普通函数
此时
this指向window
Cat.prototype.sayName = () => {
console.log(this === window) //true
return this.name
}
const cat = new Cat('mm');
cat.sayName()
箭头函数有几个使用注意点。
-
箭头函数没有自己的
this对象 -
不可以当作构造函数,也就是说,不可以对箭头函数使用
new命令,否则会抛出一个错误。 -
不可以使用
arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。 -
不可以使用
yield命令,因此箭头函数不能用作 Generator 函数。
Generator 函数:
ES6 提供的异步编程解决方案,asycn是他的语法糖,相当于自动执行generator函数;
-
他用function * 来声明,内部使用yield来暂停;会返回一个遍历器对象; 通过next方法遍历到下一个内部状态;done可以用来判断是否有下一个状态;
-
for of 可以遍历 具有迭代器的对象,所以可以遍历generator函数
区别就是 generator不是为了异步而设计的,promise和async 是专门为了处理异步操作的;
面试题:
- 箭头函数为什么不能用作构造函数:因为没有自己的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
}
- 箭头函数内可以使用arguments?
不可以,获取参数可以通过...args 的形式
- 箭头函数可以作为generator函数吗?
不可以, 因为内部不能使用yeild
- 箭头函数的this指向
在编译时候就确定,继承外层作用域的this; 如果箭头函数定义在全局,那么就指向全局对象