浅谈javascript中的call、apply、bind(2)

function Animal(name,weight){ this.name = name; this.weight = weight; } function Cat(){ Animal.call(this,'cat','50'); //Animal.apply(this,['cat','50']); this.say = function(){ console.log("I am " + this.name+",my weight is " + this.weight); } } var cat = new Cat(); cat.say();//I am cat,my weight is 50

当通过new运算符产生了cat时,Cat中的this就指向了cat对象,而继承的关键是在于Cat中执行了Animal.call(this,'cat','50') 这句话,在call中将this作为thisArgs参数传递,于是Animal方法中的this就指向了Cat中的this,而cat中的this指向的是cat对象,所以Animal中的this指向的就是cat对象,在Animal中定义了name和weight属性,就相当于在cat中定义了这些属性,因此cat对象便拥有了Animal中定义的属性,从而达到了继承的目的。 

应用场景二:移花接木

在讲下面的内容之前,我们首先来认识一下JavaScript中的一个非标准专业术语:ArrayLike(类数组/伪数组)

ArrayLike 对象即拥有数组的一部分行为,在DOM中早已表现出来,而jQuery的崛起让ArrayLike在JavaScript中大放异彩。ArrayLike对象的精妙在于它和JS原生的Array类似,但是它是自由构建的,它来自开发者对JavaScript对象的扩展,也就是说:对于它的原型(prototype)我们可以自由定义,而不会污染到JS原生的Array。

ArrayLike对象在JS中被广泛使用,比如DOM中的NodeList, 函数中的arguments都是类数组对象,这些对象像数组一样存储着每一个元素,但它没有操作数组的方法,而我们可以通过call将数组的某些方法`移接`到ArrayLike对象,从而达到操作其元素的目的。比如我们可以这样遍历函数中的arguments:

function test(){ //检测arguments是否为Array的实例 console.log( arguments instanceof Array, //false Array.isArray(arguments) //false ); //判断arguments是否有forEach方法 console.log(arguments.forEach); //undefined // 将数组中的forEach应用到arguments上 Array.prototype.forEach.call(arguments,function(item){ console.log(item); // 1 2 3 4 }); } test(1,2,3,4);

除此之外,对于apply而言,我们上面提到了它独有的一个特性,即apply接收的是数组,在传递给调用函数的时候是以参数列表传递的。 这个特性让apply看起来比call 略胜一筹,比如有这样一个场景:给定一个数组[1,3,4,7],然后求数组中的最大元素,而你知道,数组中并没有获取最大值的方法,一般情况下,你需要通过编写代码来实现。而我们知道,Math对象中有一个获取最大值的方法,即Math.max(), max方法需要传递一个参数列表,然后返回这些参数中的最大值。而apply不仅可以将Math对象的max方法应用到其他对象上,还可以将一个数组转化为参数列表传递给max,看代码就能一目了然:

var arr = [2,3,1,5,4]; Math.max.apply(null,arr); // 5

以上便是call和apply比较经典的几个应用场景,熟练掌握这些技巧,并把这些特性应用到你的实际项目中,会使你的代码看起来更加耐人寻味!

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgyxwy.html