相同点:“可让一个对象调用另外一个对象的方法”
不一样点:html
实际上,apply和call实现的功能是同样的,只是传入的参数不一样而已。数组
示例:app
function add(a,b){ return a+b; } function sub(a,b){ return a-b; } var a1 = add.apply(sub,[4,2]); //sub调用add的方法 var a2 = sub.apply(add,[4,2]); alert(a1); //6 alert(a2); //2 /*call的用法*/ var a1 = add.call(sub,4,2);
Math.max()
计算数组最大值由于Math.max()
不支持数组的方式,只能Math.max(a,b,c....)
。
根据apply的特色来实现这一功能,Math.max.apply(null,[1,2,3])
,由于没有新的对象调用Math的max方法,因此只是传入null来利用apply的特性帮助进行计算而已。函数
apply会将数组中的每一个元素一个个传入给Math.max()。也就至关于Math.max.call(null,1,2,3)
this
同理能够用Math.min.apply(null,[1,2,3])
计算数组最小值.net
注意:在ES6中就更加简单了,
Math.max.apply(...[1,2,3])
数组的push方法是不能push数组的,可是能够同时push多个元素,所以能够利用apply的特性prototype
var a = [1,2,3]; var b = [4,5,6]; Array.prototype.push.apply(a,b);//apply会将为b中每个元素执行一次push方法。返回值是push后数组a的长度
一样在ES6中只须要a.push(...b)
,就能够实现。code
参考连接:
apply()与call()的区别
首先来看一个问题,用typeof来检验类型有什么缺点呢?htm
答案是typeof没法准确地检验对象类型。对象
typeof null //object typeof [] //object
比较好的方式就是用 Object.prototype.toString.call()
来进行检验。
var a = {}; var b = []; var c = 1; Object.prototype.toString.call(a);//[object,Object] Object.prototype.toString.call(b);//[object,Array] Object.prototype.toString.call(c);//[object,Number] //判断a是不是对象类型 Object.prototype.toString.call(a) === "[object,Object]"
注意:使用obj.toString()是不能获得类型的。
缘由:Array,Function等类型做为Object的实例,都重写的了toString方法。所以在调用时,是调用了重写后的方法,而不是原型链上的toString()方法
var arr=[1,2,3]; console.log(Array.prototype.hasOwnProperty("toString"));//true console.log(arr.toString());//1,2,3 delete Array.prototype.toString;//delete操做符能够删除实例属性 console.log(Array.prototype.hasOwnProperty("toString"));//false console.log(arr.toString());//"[object Array]"
删除了重写的方法后,使用obj.toString()也就至关于调用原型链的方法了,即Object.prototype.toString.call()
参考连接:
能够经过如下方式封装成一个函数,语义更加清晰
export function typeOf (param) { return Object.prototype.toString.call(param).match(/\s+(\w+)/)[1] //正则匹配 }
Vue中能够定义成全局函数
//main.js Vue.prototype.typeof = function (param) { return Object.prototype.toString.call(param).match(/\s+(\w+)/)[1] } // 组件中调用 this.typeof([])//Array