JavaScript中的call()

来源:互联网 发布:百分百qq综合采集软件 编辑:程序博客网 时间:2024/06/03 13:33

        同样的call()方法,继承自Function.prototype.call(),所以只能被函数调用,不能被函数对象以外的对象调用(Javascript中函数和对象,有着错综复杂的关系,理解两者的关系,是非常重要的)。

      方法:

        func.call(thisarg, arg1, arg2....)(参数就不多说明了)

        定义:

        该call()方法调用具有给定this值的函数和单独提供的参数。(意思就是,在这里其实就是一次func(arg..)方法的调用,但是呢,this值我们会给你指定,不在使用默认的this值,参数呢,我们也会给你传)

        那么,函数调用是什么呢?就是把为调用的这个函数(func())传递控制权和参数,传递的参数并不只有我们定义的实参,还有两个附加的参数;this和arguments,这两个参数,本来是系统指定的,而call()方法,就是为了自己手动指定这个this值。那么,你这个操作,有什么好处呢?我将在后面讨论。

先来看一下,直接调用函数和采用了call()调用后的区别。

    function A() {        this.name = "fun";        this.sayName = function () {            alert(this.name);        }    }    function B() {    }    var a = new A();    var b = new B();    //1.直接进行函数调用    A();    //其实就是执行了以下操作    (function A() {        //系统初始化this值        //这里this值绑定在全局对象        alert(this);        this.name = "fun";        this.sayName = function () {            alert(this.name);        }    })()                          //执行完毕,返回undefined    //2.call()方法的调用    A.call(b);    //以下为执行过程    (function A(){        //前面说过call()方法会为函数指定this值        //相当于this = b,但是函数内部,不能为this赋值        //所以只能老老实实的用b替换this        b.name = "fun";        b.sayName = function () {            alert(b.name);        };    })()                           //执行完毕,返回undefined    b.sayName();    //获得对象b的所有实例属性    alert(Object.getOwnPropertyNames(b));

PS:执行过程只是为了说明两者的区别,执行代码时,请注释掉,执行结果我就不说了,感觉自己动手试一下最好。

       可以看出,直接调用,就是把函数A执行了一次,并没有什么明显的影响,那么,使用call()方法呢,其实就是为b对象添加了两个属性。结果就是,b对象获得了函数A的所有属性,就是我们所说的继承了吧。不过这是一个不完整的继承,只有b对象继承了,要让每个构造器B的实例都继承A的属性,可以这样

    function B() {        A.call(this);    }
至于为什么每个B的新实例都能继承,因为在var b = new B();时,你看B()不就是执行函数B吗,而在这个过程中,this值,又被绑定在了新实例(这里的b)上了,又绕回去了。

而另一种用法呢,无非就是方法的“短暂继承”,比如说这样:

function Cat() {        this.kind = "橘猫";        this.noise = "喵 喵";        this.sound = function () {            alert(this.kind+" : "+this.noise);        }    }    function Dog() {        this.kind = "二哈";        this.noise = "嗷嗷嗷";    }    var cat = new Cat();    var dog = new Dog();    //我有一只狗和一只猫,可是狗不会叫    //我寻思着,让猫用call()方法教它两句    //先让猫叫一声    cat.sound();                //橘猫 : 喵 喵    //cat.sound也是个函数,就如同前面的A了    //而这个函数是被当作方法调用的    // 所以this被指定为调用该方法的对象(cat)    //以下为具体执行过程(注意注释掉)    (function () {      alert(cat.kind+" : "+cat.noise);    })();    //下面是我的狗要着叫一声    cat.sound.call(dog);         //二哈 : 嗷嗷嗷    //这一次的呢,系统为this指定的值cat    //又被call()无情的改为了dog    //执行过程是这样    (function () {        alert(dog.kind+" : "+dog.noise);    })();    //虽然二哈叫了一声,但感觉这不是什么正经狗    // 以后还是别让它叫了    alert(dog.hasOwnProperty("sound")); //false

        总的来说,还是在函数执行过程中,为this重新指定值,殊途同归,只是用在构造函数身上时,它就完成了继承,而用在被当作方法调用的函数上时,就是一次“短暂的继承”。

        还有一个比较有意思的问题就是,为什么下面两个函数返回true,理解函数和对象的关系,对JavaScript学习,是有很大帮助的

    alert(Object instanceof Function);  //true    alert(Function instanceof Object);  //true


原创粉丝点击