this
有四种绑定方式,分别是默认绑定,隐式绑定,显示绑定和new
绑定,四种绑定方式根据this
不同的使用场景进行区分。从优先级的角度来说new绑定
>显式绑定
>隐式绑定
>默认绑定
。
一. 默认绑定
this
默认是绑定到window
上。
console.log(this === window); //true
函数独立调用,默认this
绑定也是绑定全局,它是不带任何修饰的绑定。
var num = 1;
function fn(){
console.log(this.num);
};
fn();
被嵌套的函数独立调用时,this
默认绑定到window
。
var num = 1;
var obj = {
num:2,
fn(){
function test(){
console.log(this.num);
};
test();
}
};
obj.fn(); //1
虽然test
函数被嵌套在obj.fn
函数中,但test
函数是独立调用,而不是方法调用。所以this
默认绑定到window
上,上例等同于:
function fn(){
(function(){
console.log(this.num);
})();
};
var num = 1;
var obj = {
num:2,
fn:fn
};
obj.fn(); //1
自执行函数是自己执行,没有被调用,this
不是函数被定义时绑定,而是函数被调用时被绑定。所以自执行函数中的this
一直指向的是window
(非严格模式下)。
二. 隐式绑定
函数被调用时有上下文对象,那么this
会绑定这个上下文对象,代码如下:
function fn() {
console.log(this.num);
};
var num = 1;
var obj = {
num: 2,
fn: fn
};
obj.fn(); //2
fn
函数被调用时是指向obj
对象,当函数引用有上下文对象时,隐式绑定就会把函数调用中的this
绑定到这个上下文对象,简单来说函数中的this总指向调用它的对象。
还有一点需要注意的是对象属性引用链中只有最顶层或者说最后一层会影响调用位置。
function fn() {
console.log(this.num);
};
var num = 1;
var obj2 = {
num: 3,
fn: fn
};
var obj = {
num: 2,
obj2: obj2
};
obj.obj2.fn(); //3
三. 显示绑定
显示绑定就是通过call
,apply
,bind
改变this
指向。
function fn() {
console.log(this.num);
};
var num = 1;
var obj2 = {
num: 3
};
var obj = {
num: 2,
fn: fn
};
obj.fn.call(obj2); //3
obj.fn.call(window); //1
四. new绑定
这个就是通过构造函数给新new
出来的对象添加属性和方法。
function fn(param){
this.param = param;
};
let fn2 = new fn('hello world');
console.log(fn2); //{ param : 'hello world' };