CodeSky 代码之空

随手记录自己的学习过程

Javascript call()与apply()

2014-07-23 12:04分类: JavaScript评论: 0

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

1function SpecialArray() {
2    var values = new Array();
3
4    values.push.apply(values, arguments);
5
6    values.toPipedString = function() {
7        return this.join("|");
8    };
9
10    return values;
11}
12
13var colors = new SpecialArray("red", "blue", "green");
14console.log(colors.toPipedString());
15

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

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

1function factorial(num) {
2    if (num <= 1) {
3        return 1;
4    } else {
5        return num * arguments.callee(num - 1);
6    }
7}
8

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

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

1function SuperType() {
2    this.colors = ["red", "blue", "green"];
3}
4
5function SubType() {
6    SuperType.call(this);
7}
8
9var instance1 = new SubType();
10instance1.colors.push("black");
11console.log(instance1.colors);
12
13var instance2 = new SubType();
14console.log(instance2.colors);
15

需要传入参数时:

1function SuperType(name) {
2    this.name = name;
3}
4
5function SubType() {
6    SuperType.call(this, "Nicholas");
7
8    this.age = 29;
9}
10
11var instance = new SubType();
12console.log(instance.name);
13console.log(instance.age);
14

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

1function SuperType(name) {
2    this.name = name;
3    this.colors = ["red", "blue", "green"];
4}
5
6SuperType.prototype.sayName = function() {
7    console.log(this.name);
8};
9
10function SubType(name, age) {
11// 继承属性
12    SuperType.call(this, name);
13
14    this.age = age;
15}
16
17// 继承方法
18SubType.prototype = new SuperType();
19SubType.prototype.constructor = SubType;
20SubType.prototype.sayAge = function() {
21    console.log(this.age);
22};
23
24var instance1 = new SubType("Nicholas", 29);
25instance1.colors.push("black");
26console.log(instance1.colors);
27instance1.sayName();
28instance1.sayAge();
29
30var instance2 = new SubType("Grey", 27);
31console.log(instance2.colors);
32instance2.sayName();
33instance2.sayAge();
34
35

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

评论 (0)