this
this可以分为全局的this, 和 函数内的this。全局的this毫无疑问指向window对象。而函数内的this,是随着函数的执行环境进行变化的。代码如下
// 全局this
console.log(this) // window
// 函数内的this
function test(){
console.log(this)
}
test() // 打印出 window 因为test()函数在全局调用
this的指向如何变化
this 的指向随着函数执行环境而变化。
当函数作为对象的方法调用时,this 指向该对象。
var obj = {
a: 1,
getA: function(){
alert ( this === obj );
// 输出:true
} };
当函数作为普通函数调用时,this 指向全局window对象。
function test(){
console.log(this)
}
test() // 打印出 window 因为test()函数在全局调用
当函数作为构造函数调用时,this指向这个对象。
构造函数的外 表跟普通函数一模一样,它们的区别在于被调用的方式。当用 new 运算符调用函数时,该函数总 会返回一个对象,通常情况下,构造器里的 this 就指向返回的这个对象,见如下代码:
var MyClass = function(){
this.name = 'sven';
};
var obj = new MyClass(); alert ( obj.name );
// 输出:sven
但是,如果构造函数返回了另外一个对象,则里面的this就会指向这个返回的对象。
var MyClass = function(){
this.name = 'sven';
return {
name: 'anne'
}
};
var obj = new MyClass();
alert ( obj.name );
// 输出:anne
Function.prototype.call 或 Function.prototype.apply 调用。
用 Function.prototype.call 或 Function.prototype.apply 可以动态地 改变传入函数的 this:
var obj1 = {
name: 'sven',
getName: function(){
return this.name;
}
};
var obj2 = { name: 'anne' };
console.log( obj1.getName() ); // 输出: sven
console.log( obj1.getName.call( obj2 ) ); // 输出:anne
call apply 是个什么???
都知道call,apply可以用来改变this的指向,但是这个说法太书面了,不好理解。其实call,apply是Function 原型对象上的两个方法。他可以隐式的给一个对象添加一个方法,并且默认执行这个方法。比如上面的代码中 obj1.getName.call( obj2 ) 实际上给对象obj2添加了obj1的getName()方法,所以最终输出anne。
说的再通俗一点,其实是把obj1 的getName方法,作为obj2的方法直接执行了。
call和apply的区别
call apply的作用一样,区别仅在于参数形式不一样。
func.apply( null, [ 1, 2, 3 ] ); // 第二个参数 为数组或类数组
func.call( null, 1, 2, 3 ); // 第二个参数 依次传入
搞清楚这些以后,就可以愉快的理解一些高阶函数。
关注我 一起回忆 《javaScript高级程序设计》《javaScript设计模式中》你没注意过的细节