Appearance
五种绑定
方式:默认绑定、隐式绑定、显示绑定、new 绑定、箭头函数绑定
优先级:显式绑定 > 隐式绑定 > 默认绑定 new 绑定 > 隐式绑定 > 默认绑定
默认绑定
当函数调用没有任何前缀的情况下,this 在非严格模式下指向 window,在严格模式下指 向 undefined,在严格模式下调用不在严格模式下的函数,并不影响 this 的返回
function fn1() {
console.log(this); //window
};
function fn2() {
"use strict";
console.log(this); //undefined
};
var name = '听风是风';
function fn3() {
console.log(this); //window
};
(function () {
"use strict";
fn3();
}());
隐式绑定
1. 如果函数调用时,前面存在调用它的对象,那么 this 就会隐式绑定到这个对象上
function fn() {
console.log(this.name);
};
let obj = {
name: '听风是风',
func: fn
};
obj.func() //听风是风
2. 如果函数调用前存在多个对象,this 指向距离调用自己最近的对象
function fn() {
console.log(this.name);
};
let obj = {
name: '行星飞行',
func: fn,
};
let obj1 = {
name: '听风是风',
o: obj
};
obj1.o.func() //行星飞行
隐式丢失
- 作为参数传递以及变量赋值
var name = '行星飞行';
let obj = {
name: '听风是风',
fn: function () {
console.log(this.name);
}
};
function fn1(param) {
param();
};
fn1(obj.fn);//行星飞行
例子中我们将 obj.fn 也就是一个函数传递进 fn1 中执行,这里只是单纯传递了一个函数而已,this并没有跟函数绑在一起,所以this丢失这里指向了window。
- 变量赋值,其实本质上与传参相同
var name = '行星飞行';
let obj = {
name: '听风是风',
fn: function () {
console.log(this.name);
}
};
let fn1 = obj.fn;
fn1(); //行星飞行
3.隐式绑定丢失并不是都会指向全局对象
var name = '行星飞行';
let obj = {
name: '听风是风',
fn: function () {
console.log(this.name);
}
};
let obj1 = {
name: '时间跳跃'
}
obj1.fn = obj.fn;
obj1.fn(); //时间跳跃
虽然丢失了 obj 的隐式绑定,但是在赋值的过程中,又建立了新的隐式绑定,这里this就指向了对象 obj1。
显示绑定
通过 call、apply 以及 bind 方法改变 this 的行为
let obj1 = {
name: '听风是风'
};
let obj2 = {
name: '时间跳跃'
};
let obj3 = {
name: 'echo'
}
var name = '行星飞行';
function fn() {
console.log(this.name);
};
fn(); //行星飞行
fn.call(obj1); //听风是风
fn.apply(obj2); //时间跳跃
fn.bind(obj3)(); //echo ,因为bind非立即执行,详情参考笔记的this指向call,apply,bind
注意,如果在使用 call 之类的方法改变 this 指向时,指向参数提供的是 null 或者 undefined,那么 this 将指向全局对象。
let obj1 = {
name: '听风是风'
};
let obj2 = {
name: '时间跳跃'
};
var name = '行星飞行';
function fn() {
console.log(this.name);
};
fn.call(undefined); //行星飞行
fn.apply(null); //行星飞行
fn.bind(undefined)(); //行星飞行
new 绑定
new 执行了什么
(1) 创建一个新对象
(2) 将构造函数的作用域赋给新对象(因 此 this 就指向了这个新对象)
(3) 执行构造函数中的代码(为这个新对象添加属 性)
(4) 返回新对象
function Fn(){
this.name = '听风是风';
};
let echo = new Fn(); //this将指向新对象echo上
echo.name//听风是风
箭头函数
准确来说,箭头函数中没有 this,箭头函数的 this 指向取决于外层作用域中的 this,外 层作用域或函数的 this 指向谁,箭头函数中的 this 便指向谁。