摘要:首先,我们判断是否存在方法,然后,若不存在,向对象的原型中添加自定义的方法。指向调用它的对象。总之三个的使用区别都是用来改变函数的对象的指向的第一个参数都是要指向的对象都可以利用后续参数传参是返回对应函数,便于稍后调用,是立即调用
apply和call都是为了改变某个函数运行时的上下文而存在的(就是为了改变函数内部this的指向),Function对象的方法,每个函数都能调用;
使用apply或call方法,其运行的上下文指向第一个参数,apply的第二个参数是一个参数数组,call的第二个及其以后的参数都是数组里面的元素。
apply和call的常用用法:
数组之间的追加;
例如:多维数字转一维
let arr=[1,[7,8],[5,6]]; res=[].concat.apply([],arr)
扩充作用域拥有Math的min和max方法,获取数组中的最大值和最小值;
let numbers = [5, 458 , 120 , -215 ];
let maxInNumbers = Math.max.apply(Math, numbers), //458
maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458
验证是否是数组;
function isArray(obj){
return Object.prototype.toString.call(obj) === "[object Array]" ;
}
让类数组拥有方法;
比如: arguments对象,获取到的文档节点等,并没有数组的那些方法:
Array.prototype.slice.apply(argument);
//理论上来说这个比较快,直接在原型上查找slice方法
//但实际上比较慢
或者
[].slice.apply(arguments);
//理论上来说这个比较慢,因为要Array做一个实例化再查找slice方法
//实际上比较快,因为现在的各种自动化工具会把上一种方法转换为这种,而第二种代码比较简洁,所以会比较快;
也是改变函数体内this的指向,bind()是es5中的方法,bind会创建一个新函数,称为绑定函数,当调用这个函数的时候,绑定函数会以创建它时传入bind()方法的第一个参数作为this,传入bind()方法的第二个及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数;
例如:(后面的代码皆取自张鑫旭大神的博客)
var button = document.getElementById("button"), text = document.getElementById("text"); button.onclick = function() { alert(this.id); // 弹出text }.bind(text);
但由于ie6~ie8不支持该方法,所以若想在这几个浏览器中使用,我们就要模拟该方法,这也是面试常考的问题,模拟的代码如下:
if (!function() {}.bind) { Function.prototype.bind = function(context) { var self = this; var args = Array.prototype.slice.call(arguments); return function() { return self.apply(context, args.slice(1)); } }; }
上面的代码中this的指向是个容易理解错的地方。
首先,我们判断是否存在bind方法,然后,若不存在,向Function对象的原型中添加自定义的bind方法。
这里面var self = this这段代码让我很困扰,按理说,prototype是一个对象,对象的this应该指向对象本身,也就是prototype,但真的是这样吗。看看下面的代码:
function a(){}; a.prototype.testThis = function(){console.log(a.prototype == this);}; var b = new a(); b.testThis();//false
显然,this不指向prototype,而经过测试,它也不指向a,而指向b。所以原型中的this值就明朗了。指向调用它的对象。
Array.prototype.slice.call(arguments);
上面这段代码,它的作用是将一个类数组转化为真正的数组,arguments是传给call的那个上下文(由于arguments自己没有slice方法,这里属于借用Array原型的slice方法)。而且经过测试,若果你不给slice传参数,那就等于传了个0给它,结果就是返回一个和原来数组一模一样的副本。
这之后的代码就很好理解,返回一个函数,该函数把传给bind的第一个参数当做执行上下文,由于args已经是一个数组,排除第一项,将之后的部分作为第二部分参数传给apply,前面讲过apply的用法。
如此,我们自己的这个bind函数的行为就同es5中的bind一样了。
总之三个的使用区别:
都是用来改变函数的this对象的指向的;
第一个参数都是this要指向的对象;
都可以利用后续参数传参;
bind是返回对应函数,便于稍后调用,apply、call是立即调用;
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/102180.html
摘要:绑定函数被调用时,也接受预设的参数提供给原函数。一个绑定函数也能使用操作符创建对象这种行为就像把原函数当成构造器。 一直很难理解js中的call apply bind,在w3schools,mdn阅读了,也看了很多相关的文章,今天我来写下我理解的call apply bind 首先创建一个函数 function man(){} man.prototype = { name: ...
摘要:理解文章中已经比较全面的分析了在中的指向问题,用一句话来总结就是的指向一定是在执行时决定的,指向被调用函数的对象。与和直接执行原函数不同的是,返回的是一个新函数。这个新函数包裹了原函数,并且绑定了的指向为传入的。 理解 JavaScript this 文章中已经比较全面的分析了 this 在 JavaScript 中的指向问题,用一句话来总结就是:this 的指向一定是在执行时决定的,...
摘要:它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用类似的还有。总结关键字就是,谁调用我,我就指向谁。注意由于已经被定义为函数内的一个变量。因此通过关键字定义或者将声明为一个形式参数,都将导致原生的不会被创建。 题目 封装函数 f,使 f 的 this 指向指定的对象 。 输入例子 bindThis(function(a, b) { return this.test +...
摘要:它们有明确的和成员函数的定义,只有的实例才能调用这个的成员函数。用和调用函数里用和来指定函数调用的,即指针的指向。同样,对于一个后的函数使用或者,也无法改变它的执行,原理和上面是一样的。 函数里的this指针 要理解call,apply和bind,那得先知道JavaScript里的this指针。JavaScript里任何函数的执行都有一个上下文(context),也就是JavaScri...
摘要:和区别其实他们的作用是一样的,只是传递的参数不一样而已。接受个参数,第一个参数指定了函数体内对象的指向,第二个参数为数组或者一个类数组。看个栗子一个有意思的事在中,多次是无效的。而则会立即执行函数。 背景 前两天在做小程序的需求的时候用到bind的时候才想起自己对这三的东西的了解比较浅薄,这个时候用的时候就有点怕。时候还是要好好学习下,理解下怎么玩。 正文 先说call 和 apply...
阅读 2372·2021-11-24 10:26
阅读 2564·2021-11-16 11:44
阅读 1694·2021-09-22 15:26
阅读 3564·2021-09-10 11:11
阅读 3177·2021-09-07 10:25
阅读 3614·2021-09-01 10:41
阅读 1001·2021-08-27 13:11
阅读 3498·2021-08-16 11:02