谈谈JavaScript 中call apply 那点简单事
平常是否遇到过call apply 的问题 比如说
- 怎么利用call、apply来求一个数组中最大或者最小值
- 如何利用call、apply来做继承
- apply、call的区别和主要应用场景
这些有可能在面试时候 会问到不知道你清楚吗 如果你清楚没有必要太仔细看 不清楚可以看看下面我谈谈
首先那这三个点那 在我们平常中使用是用来改变函数执行上下文的 说白了就是改变this的指向
上段code
function Person (name) { this.name = name } Person.prototypr = { showname: function() { alert(this.name) } } var p = new Person('xiaoming'); p.showname(); //这里打印 xiaoming 这个相信大家都知道答案复制代码
接着来
var a = { name: 'xiaowang'}alert(a.showname) //这里打印的 undefined 很明显a 对象里面没有showname复制代码
这里我们想到一个方法就是用Person原型的showname方法 这里八竿子打不着关系 于是call apply 来帮助了
Person.showName.call(a);Person.showName.apply(a);Person.showName.bind(a)();//发生了什么 都是打印了 牛逼了 来解释下这些个名次复制代码
call apply 其实差不多 就是参数的形式不一样
call() 参数接受的都是一个一个 call(this, arg1, arg2, ....)
apply() 参数接受的是一个数组 apply(this, [arg1, arg2, ....])擦 这不差不多吗 就一个参数的形式不一样而已 话不多说来上code比如面试常问到的- 求数组中的最大和最小值
var arr = [4,3,6,1,7,2,0,9] 平常我我们见到是这样 console.log(Math.max(3,4,2,1,0)) 打印是4 达到了预期 如果数据很多岂不是要一直写下去喽 利用apply Math.max.apply(Math, arr) //打印 9 利用call Math.max.apply(Math, 4,3,6,1,7,2,0,9) //打印 9复制代码
解释下上面是啥意思 arr是没有max的方法的 可是Math是有的
所以利用call 或者apply 来将Math的方法拿过来用- 数组之间的添加
var a =[1,2,3] var b =[4,5,6] 需求是将b追加到a中 这个使用我们就用到了apply Array.prototype.push.apply(a, b); console.log(a) //[1,2,3,4,5,6]复制代码
解释下上面 真数组才有push的方法 这里是将 a 拿到b这里 一个个添加到a中
- 类(伪)数组使用数组方法先解释下啥叫类(伪)数组 先看下数组长啥样
var a = new Array('a','b')console.log(a) // 0:'a' 1:'b' length:2但是如果是这样的是数组吗?var arrayLike = { 0: 'a', 1: 'b', length: 2}所以说具有length属性,并且可以通过0、1、2…下标来访问其中的元素,但是没有Array中的push、pop等方法。var a = { 0: 'xiaoming', 1: 'xiaowang', 2: 'xiaoxing', length: 3}var arr = Array.prototype.slice.call(a)Array.prototype.slice=function(start, end) { var result = new Array() var start = start || 0; var end = end || this.length for (var i = start;i
这里解释下 注意点数据结构必须是以数字为下标而且一定要有length属性
数组的slice 方法底层的实现就是这个 将这个方法拿过来了到a 这个对象中 最后放回数组["xiaoming", "xiaowang", "xiaoxing"]- 用到继承
var Person = function (name, age) { this.name = name; this.age = age;};var Girl = function (name) { Person.call(this, name);};var Boy = function (name, age) { Person.apply(this, arguments);}var g1 = new Girl ('qing');var b1 = new Boy('qianlong', 100);等同于var Person = function (name, age) { this.name = name; this.age = age;};var Girl = function (name, age) { this.name = name; this.age = age;};var Boy = function (name, age) { this.name = name; this.age = age;}var g1 = new Girl ('qing');var b1 = new Boy('qianlong', 100);复制代码
解释下 Person.call 可以看成把Person 拿到 GirlBoy中使用
简单部一个 bind()方法会创建一个新函数,称为绑定函数。
bind是ES5新增的一个方法,不会执行对应的函数(call或apply会自动执行对应的函数),而是返回对绑定函数的引用。