call定义
语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明:call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
又遇见了各种专业名词了吧,没有经过长期的文档摧残是无法快速掌握一个方法的精髓的,一起做几个小实验吧
var myName = 'goudan';
var myAge = 13;
function showMsg(msg){
return msg + ''.toLowerCase();
}
showName(myName); // 'goudan'
这段代码很容易就能看懂,在实际开发工作中,我们会处理不同的数据集合,这时候var单一变量已经无法满足胃口,需要通过json的形式来存储数据
var person = {
name:"kyogre",
age:13,
hobby:"coding"
}
var newPerson ={
name:'dachui',
age:99,
hobby:'eat'
}
function showMsg(msg){
return msg + ''.toLowerCase();
}
showMsg(person.name) // 'kyogre'
showMsg(newPerson.name) // 'dachui'
存储数据的方式发生了改变,但是我们处理数据的方式还是那么。。。古老,如果业务复杂一点
function format(msg){
return msg+''.toLowerCase();
}
function show(msg){
return '信息的内容是:'+ format(msg);
}
show(person.name) // '信息内容是:kyogre'
show(newPerson.name) // '信息内容是:dachui'
显示的传递上下文对象 (穿参)使得业务越来越复杂,这种叠加会让开发变得冗余和难以解读,bug和闭包横飞
那我们看看通过this如何清晰解决问题
通常this不会指向函数自身,而是调用函数的对象主体。当然,我们可以强制让function自身成为对象主体,这个以后咱们讨论; json本身就是对象,我们是否可以这样:
var person = {
name:"kyogre",
age:13,
hobby:"coding"
}
var newPerson ={
name:'dachui',
age:99,
hobby:'eat'
}
function format(){
return this.name+''.toLowerCase();
}
问题来了,不让穿参这个format中的this指向谁呢? 指向调用format的对象本身,可是调用主体并不明确,可能是person也可能是newPerson,这时回过头看看call的定义吧:调用一个对象的一个方法,以另一个对象替换当前对象。 将函数内部执行上下文对象由原始对象替换为指定对象
var name = '我叫window'; //全局变量 非严格模式下都为 window的属性 window.name;
function format(){
return this.name+''.toLowerCase();
}
format(); //'我叫window';
不要惊慌,本身他就是这样window会作为调用*作用域链函数的对象主体;这里的this默认为 window, 用person对象代替window这个默认this主体去执行format会怎么样呢
format.call(person);
// kyogre
format.call(newPerson);
// dachui
function show(){
return '信息的内容是:'+ format.call(this);
}
show.call(person); // 信息的内容是:kyogre
感觉自己了解了this和call的小明,已经肆无忌惮的笑了起来,这样他就可以从繁重的回调与参数传递中解脱了,并且能够实现方法的初级模块化。可是事情并没有这么简单。。。知道的越多,不知道的就越多 ;-)
下面可以用call做一些平常的操作
function isArray(object){
return Object.prototype.toString.call(object) == '[object Array]';
}// 借用Object原型上的toString方法来验证下对象是否是数组?
function accumulation(){
return [].reduce.call(arguments,(a,b)=>{return a+b}
}//让不能使用数组方法的arguments类数组集合使用借用数组的reduce方法
return Array.prototype.forEach.call($$('*'),(item)=>{item.style.border = '1px solid red';}
//把类数组节点集合通过call借用数组的forEach方法实现。。。你自己在控制台用一下就知道,O(∩_∩)O~
真正决定this指向谁的并不一定是能看的见的对象,很多情况this会被隐性改变,this没有谁调用就指向谁那么简单; 如果想要深入理解,我们下次有机会谈一下执行上下文和词法作用域吧。。。。