素材牛VIP会员
用寄生构造函数来扩展功能的问题
 ti***nx  分类:JavaScript  人气:706  回帖:2  发布于6年前 收藏

在博客看到这样一个例子:

function specialArray(){
    var values = new Array();
    values.push.apply(values,arguments);
    values.toPipedString = function(){
        return this.join('|');
    }
    return values;
};

var color = new specialArray('blue','red','yellow')
alert(color.toPipedString())

对这句values.push.apply(values,arguments)不太明白,首先是push不是应该是一个方法吗?这样的写法很奇怪;其次apply不是用来冒充对象的吗?虽然我知道这句话的作用是把传进去的参数添加到values这个数组末尾,但是具体是怎么实现的请大神指点一下,谢谢!

 标签:javascript

讨论这个帖子(2)垃圾回帖将一律封号处理……

Lv7 码师
陌***4 软件测试工程师 6年前#1

apply你要说是用来冒充对象的,似乎也有那么点儿形象。
这个方法的初衷是这样的:比如数组实例的原型对象中有push方法,但对象实例并没有,那我也想用,怎么办呢?

let obj = {};
[].push.apply(obj, ["a", "b", "c"]);
console.log(obj);
// 0:"a", 1:"b", 2:"c"

这样实际上为对象使用了push方法,但在你的问题中,values本身是一个数组,它的原型对象中本身就有push方法,它为什么还要这么写呢?这是因为他想利用apply方法的参数特性。push方法接受的单个值(或者说对象)而apply方法的第二个参数是一个数组。所以对于想将一个数组push到另一个数组中时,可以:

var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
[].push.apply(arr1, arr2);
console.log(arr1);
// [1, 2, 3, 4, 5, 6]
// 当然它有更简单的写法: console.log(arr1.concat(arr2));

在你的例子中:

function specialArray(){
    var values = new Array();
    values.push.apply(values,arguments);
    // values.push 只是为了取到push方法,然后借用它,所以这里push前面的数组是谁并不重要;
    // 只要它包含push方法即可,但为了不在程序中声明过多的变量,所以这里直接使用了已经存在的数组values;
    // arguments 是函数参数的集合,是一个数组,在这里作为apply方法的第二参数正合适。
    values.toPipedString = function(){
        return this.join('|');
    }
    return values;
};

var color = new specialArray('blue','red','yellow')
alert(color.toPipedString())
Lv5 码农
风***在 产品经理 6年前#2

首先你对apply的理解是有误的,多看下文档。
values.push.apply(values,arguments);
相当于

for(let i = 0 ; i < arguments.length ; i++){
    values.push(arguments[i])
}

更加简洁

 文明上网,理性发言!   😉 阿里云幸运券,戳我领取