JavaScript 之 this、call 和 apply

  在 JavaScript 编程中,this 关键字总是让初学者感到迷惑, Function.prototype.call 和 Function.prototype.apply 这两个方法也有着广泛的运用。

this

   JavaScript 的 this 总是会指向一个对象,而具体指向哪个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境。this 的指向大致可以分为以下 4 种:

  • 作为对象的方法调用
  • 作为普通函数调用
  • 构造器调用
  • Function.prototype.call 或 Function.prototype.apply 调用

1. 作为对象的方法调用

当函数作为对象的方法被调用时,this 指向该对象:

window.a = 0;

var obj = {
	a: 1,
	getA: function() {
		alert( this === obj );		// true
		alert( this.a );			// 1
	}
};

obj.getA();

2. 作为普通函数调用

  当函数不作为对象的属性被调用时,也就是我们常说的普通函数方式。此时的 this 总是指向全局对象也就是 window 对象。

window.a = 0;

var obj = {
	a: 1,
	getA: function() {
		return this.a;
	}
};

var getA = obj.getA;
getA();    // 0

如何来解决此 this 指向的问题呢,我们可以使用后面所讲到的 call 来改变 this 的指向,修改代码:

getA.call(obj)  // 1

这个时候 this 就指向了 obj,打印结果为 1。

3. 构造器调用

   JavaScript 中没有类,但是可以从构造器中创建对象,同时也提供了 new 操作符,使得构造器看起来更像一个类。当用 new 运算符调用函数时,该函数总会返回一个对象,通常情况下,构造器里的 this 就指向返回的这个对象,如下代码:

var MyClass = function() {
	this.name = "xiaoming";
};

var obj = new MyClass();
console.log(obj.name);			// xiaoming

4. FuncFunction.prototype.call 或 Function.prototype.apply 调用

  跟普通函数调用相比,用 Function.prototype.call 或 Function.prototype.apply 可以动态地改变传入函数的 this:

var obj1 = {
	name: "one",
	getName: function() {
		return this.name;
	}
};

var obj2 = {
	name: "two"
}

console.log( obj1.getName() );				// one
console.log( obj1.getName.call(obj2) );		// two

call 和 apply

  call 和 apply 的作用是一模一样的,都是可以动态的改变 this 的指向,区别在于传入参数形式的不同。
  apply 接受两个参数,第一个参数指定了函数体内 this 对象的指向,第二个参数为一个带下标的集合,这个集合可以为数组,也可以是类数组:

var func = function(a, b, c) {
	alert([a, b, c]); 						// 1, 2, 3
}

func.apply(null, [1, 2, 3]);

  call 传入的参数数量不固定,跟 apply 相同的是,第一个参数也是代表函数体内的 this 指向,从第二个参数往后,每个参数被依次传入函数:

var func = function(a, b, c) {
	alert([a, b, c]); 						// 1, 2, 3
}

func.call(null, 1, 2, 3);

  当使用 call 或者 apply 的时候,如果我们传入的第一个参数为 null,函数体内的 this 会指向默认的宿主对象,在浏览器中则是 window:

var func = function(a, b, c) {
	alert(this === window); 						// true
}

func.call(null, 1, 2, 3);

但如果是在严格模式下,函数体内的 this 还是为 null:

var func = function(a, b, c) {
	"use strict"
	alert(this === null); 						// true
}

func.call(null, 1, 2, 3);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值