Javascript call()与apply()

js中对于function,有callapply两种方法,在看书时前面没发现他们俩太大的作用,现在找到了一个实例,能说明apply的优点。

function SpecialArray() {
    var values = new Array();

    values.push.apply(values, arguments);

    values.toPipedString = function() {
        return this.join("|");
    };

    return values;
}

var colors = new SpecialArray("red", "blue", "green");
console.log(colors.toPipedString());

正如前面所见,我们使用了push.apply,可是为什么这里要用apply而不是直接传入,因为push接收的并不是数组,传入数组的话,给push的应该是数组中的元素,apply很好的帮助了我们,apply应用时,前面是应用的环境,而后者传入数组,会自动变为每一个元素,而call则是需要传入每一个元素而不是数组。

此外顺便借地mark一下一个arguments.callee的方法,比如

function factorial(num) {
    if (num <= 1) {
        return 1;
    } else {
        return num * arguments.callee(num - 1);
    }
}

这个方法的优点在于,在递归时不用具体的函数名,在修改函数名也没问题。

更新:
call使用在继承里是很方便的,因为prototype如前文所说有着他的不足之处(共享),而且不能传递参数,所以我们使用了call来继承,如下:

function SuperType() {
    this.colors = ["red", "blue", "green"];
}

function SubType() {
    SuperType.call(this);
}

var instance1 = new SubType();
instance1.colors.push("black");
console.log(instance1.colors);

var instance2 = new SubType();
console.log(instance2.colors);

需要传入参数时:

function SuperType(name) {
    this.name = name;
}

function SubType() {
    SuperType.call(this, "Nicholas");

    this.age = 29;
}

var instance = new SubType();
console.log(instance.name);
console.log(instance.age);

当然,混合使用依旧是其中最好的方式:

function SuperType(name) {
    this.name = name;
    this.colors = ["red", "blue", "green"];
}

SuperType.prototype.sayName = function() {
    console.log(this.name);
};

function SubType(name, age) {
// 继承属性
    SuperType.call(this, name);

    this.age = age;
}

// 继承方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function() {
    console.log(this.age);
};

var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
console.log(instance1.colors);
instance1.sayName();
instance1.sayAge();

var instance2 = new SubType("Grey", 27);
console.log(instance2.colors);
instance2.sayName();
instance2.sayAge();

SuperType构造函数定义了两个属性:namecolorsSuperType的原型定义了一个方法sayName()SubType构造函数在调用SuperType构造函数时掺入了name参数,紧接着定义了age属性,然后将SuperType实例赋值给SubType原型,在新原型上定义方法,然后就独立开来了。

植入部分

如果您觉得文章不错,可以通过赞助支持我。

如果您不希望打赏,也可以通过关闭广告屏蔽插件的形式帮助网站运作。

标签: 知识, 语法

添加新评论