对ES5中apply、call和bind三个要领的解读
JavaScript中,apply、call 和 bind 都是为了转变某个函数运行时的上下文而存在的,实在就是为了转变所挪用的函数体内部 this 的指向。
Function.prototype.apply()要领
Example
var nodeList = document.querySelectorAll("div");
Array.prototype.slice.apply(nodeList).forEach((node)=>{
console.log(node); // 输出每个div节点对象
});
代码解读:
上面是一段JS中经常运用的代码,这段代码示意的意义是,当我们猎取到一个类数组的对象的时刻怎样让它能够挪用一切数组所具有的要领。我们都晓得,一切的猎取dom元素的要领,返回的不是dom节点对象,就是包括节点对象的类数组,而类数组虽然从输出来看和数组是没什么区分的,但是在原型链上是有很大的差别的。像NodeList这个类数组就是不包括基本上一切数组的经常运用要领的,所以这个时刻就须要 借 数组的slice要领来将NodeList这个歌类数组转成真正的数组对象,如许就能够直接挪用push要领了。
Function.prototype.call()要领
Example
var nodeList = document.querySelectorAll("div");
Array.prototype.slice.call(nodeList).forEach((node)=>{
console.log(node); // 输出每个div节点对象
});
代码解读:上面这段代码和apply要领中的例子是如出一辙的,所以,实在他们两个要领的作用都是一致的,用法呢就是相似的,而为什么说是相似的呢,看下面这个例子:
Example:
var max1 = Math.max.call(null, 1,2,3);
var max2 = Math.max.apply(null, [1,2,3]);
console.log(max1); // 结果是3
console.log(max2) // 结果是3
代码解读:从上面这个例子中能够看出,call和apply的用法不同之处在于,假如所挪用的要领要领须要传入参数,那末call须要从第二个入参最先传入须要的值,而apply是在第二入参用数组来通报参数,这里要注意的是哪怕是参数只须要传入一个,也全都根据这类语法划定规矩,不然如上面的Math.max就会报TypeError,所以发起以下:当所挪用的要领是0个参数的,那随意哪一个都能够,假如是1~2个参数的发起运用call要领,假如是3个及以上的用apply要领。
Function.prototype.bind()要领
Example
var nodeList = document.querySelectorAll("div");
var nodeArray = Array.prototype.slice.bind(nodeList);
nodeArray().forEach((node)=>{
console.log(node); // 输出每个div节点对象
});
代码解读:从上面的例子看一看出bind要领只是替换了所挪用要领的this指向,并不会主动去实行这个要领,而apply和call要领是即转变了this指向,又马上实行的,所以bind平常用于不须要马上实行,只请求变动this指向的场景,如:click事宜的回调函数平常就会用bind去转变回调函数的this指向,而在click事宜触发的时刻实行。末了申明一下,bind的参数和call的参数通报是一致的,例子以下:
Example
var maxBind = Math.max.bind(null, 1,2,3);
var max = maxBind();
console.log(max); // 结果是3
结束语:上面就是javaScript关于怎样转变运行时上下文的三个要领了,下面是我本身完成的一个相似运行时转变上下文的要领,不适合在现实场景中运用,仅供人人参考:
var Person = {
context:null,
name:'小明',
say:function(greeting){
var me = this.context || this;
return greeting + me.name
}
}
Person.say.__proto__.callCopy = function(_context,greeting){
Person.context = _context;
return Person.say(greeting);
}
var world1 =Person.say('你好 ');
var world2 = Person.say.callCopy({name:'xiaoMing'},'hello ');
console.log(world1); // 你好 小明
console.log(world2); // hello xiaoMing