this到底指向什么地方,决定于函数的调用方式。
1、 指向全局变量 --- 函数被单独调用的时候
function fn() { console.log( this.a ); } var a = 2; fn(); //2 fn单独调用,this引用window
2、 指向某对象 --- 隐式绑定
隐式调用的意思是,函数调用时拥有一个上下文对象
function fn() { console.log( this.a ); } var obj = { a: 2, fn: fn }; obj.fn(); //2 this引用obj。 //说明的一点是,最后一个调用该函数的对象是传到函数的上下文对象。如: function fn() { console.log( this.a ); } var obj2 = { a: 42, fn: fn }; var obj1 = { a: 2, obj2: obj2 }; obj1.obj2.fn(); //42 this引用的是obj2. //还有一点要说明的是,失去隐式绑定的情况,如下: function fn() { console.log( this.a ); } var obj = { a: 2, fn: fn }; var bar = obj.fn; // 函数引用传递 var a = "全局"; // 定义全局变量 bar(); // "全局"
如上,虽然有隐式绑定,但是它执行的效果明显是把fn赋给bar。这样bar执行的时候,依然是函数单独调用,指向全局变量,所以输出结果如上。
3、 指向某对象 --- 显示绑定
通过call()、apply()、bind()。它们接收的第一个参数即是上下文对象,并将其赋给this。
function fn() { console.log( this.a ); } var obj = { a: 2 }; fn.call( obj ); // 2
如果我们传递第一个值为简单值,那么后台会自动转换为对应的封装对象。如果传递为null,那么结果就是在绑定默认全局变量。
4、 指向类实例
如果是一个构造函数,用new来调用,那么this指向新创建的对象。
function fn(a) { this.a = a; } var bar = new fn( 2 ); console.log( bar.a );// 2