JavaScript进阶设计模式系列——基础篇——this-call-apply

this

在JavaScript的世界中,this是一个很让人挠头的概念,为什么呢?第一,它总是指向一个对象,使用起来可以简化代码。第二,它是基于函数的执行环境进行动态绑定的,而不是在函数被声明时的环境被指定。

this的指向

作为对象的方法被调用

此时,this指向该对象。如代码所示:

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

普通函数调用

此时,指向的是全局对象。如果是在浏览器中,那么这全局对象就是window。如代码所示:

window.name = 'globalName';

var myObject = {
    name : 'bill',
    getName : function () {
        return this.name;
    }
}

var getName = myObject.getName();
console.log(getName);

构造器被调用

此时,this指向的是返回的对象。如下代码

var myClass = function () {
    this.name = 'bill';
}

var obj = new myClass();
console.log(obj.name);

注意:在构造器的调用中,有一类特殊情况。如果,在构造器中显示地返回了一个object类型的对象,那么最终的this还是指向被返回的对象。如下所示:

var MyClass = function(){
    this.name = 'bill';
    return {
        name : 'cindy'
    }
};
var obj = new MyClass();
console.log(obj.name);

被call或者apply调用

此时,this的指向有call或者apply函数的第一个参数决定。如下代码所示

var obj = {
    name : 'bill',
    getName : function () {
        return this.name;
    }
};
var obj2 = {
    name : 'cindy'
};

console.log(obj.getName());
console.log(obj.getName.call(obj2));

this丢失

啥叫丢失呢?咱们看一段代码先

var obj = {
    name : 'bill',
    getName : function(){
        return this.name;
    }
};

console.log(obj.getName());
var getName2 = obj.getName;
console.log(getName2());

为什么会丢失?因为,在将引用赋值给变量getName2之后,getName2被调用的时候,是一种普通函数调用,而普通函数调用,我们已经知道了一直指向全局对象,此时的全局对象中并没定义name的值。因此返回的是undefined。

call和apply

这俩函数,是在ECAMscript3中给Function对象定义的两个方法。实际开发过程中,这哥俩被用到的频率非常高,用处很大!

区别

首先,作用是基本一致的。都是调用对象的方法。唯一的不同就是传入参数的形式不一样
call调用的时候:

var func = function (a,b,c){
    console.log([a,b,c])
};
func.call(null,1,2,3);

apply调用:

var func = function (a,b,c){
    console.log([a,b,c])
};
func.apply(null,[1,2,3]);

小结:

区别:call传入的参数数量不固定,参数会被依次被传递.而apply使用的是一个带下标的集合,它可以是数组,或者是类数组。
相同点:他们的第一个参数都是代表的是this的指向。
关系:call是在apply的基础上包装的语法糖。
应用场景:但是两者各有不同的应用场景。call更多的是在明确知道函数接收多少参数的情况下进行使用,想要清楚看到形参和实参的对应关系,用call就对了。apply是在不知道具体参数的个数的情况下使用,apply的使用效率会更高。

用途:

  • 借用其他对象的方法
  • 改变this的指向
  • Function.prototype.bind
    注意:其他内部的原理,也是通过指定this的指向来实现的。

小结:

在JavaScript的高级应用中,弄清楚this的指向,并熟悉call和apply方法的使用,是每个想要进阶JavaScript的工程师不可避免的话题。

this的指向,分别在四种不同的情况下有不同的表现:

  1. 通过对象的方法的形式调用,始终指向该对象。
  2. 通过普通函数的形式调用的时候,始终指向全局对象。如果是在浏览器环境中,则指向全局对象是window
  3. 通过构造器访问的时候,始终指向被返回的对象
  4. 通过call和apply调用的时候,由call或者是apply方法的第一个参数来决定。

call和apply,作用一致都可以用来调用其他对象的方法和改变this的指向。两者的区别仅仅在于参数的使用方式上,call需要明确参数的个数和顺序。而apply不需要知道,一股脑通过一个集合传过去就OK了。

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值