深入js中的call,apply方法

call(),apply()方法的作用都是用来改变函数运行时的上下文(Context),那么什么是上下文呢?

关于上下文

上下文就是函数中this的值,它的值等于函数运行时,调用这个函数的对象,也就是说,上下文是可以动态改变的,随着函数执行环境的不同,它的值也会发生变化。比如:

  1. 在全局作用于中调用函数,函数的上下文为Global对象(在浏览器中为window对象),eg:
var name = 'JavaScript';
function sayName (){
  console.log(this.name);
}
// 在全局作用域中调用sayName,此时相当与window.sayName();
// 所以此时的 this = window,即函数运行时的上下文为: window对象
sayName();     
  1. 在特定对象中调用函数,this指向这个对象,eg:
function Cat(name,sound) {
  this.name = name;
  this.sound = sound;
}
Cat.prototype.speak =function () {
  console.log(`${this.name} speak ${this.sound}`);
}
var mipang = new Cat('mipang','喵喵喵~~');
// 在对象mipang中调用函数speak,此时函数speak内部的指针指向mipang
// mipang有两个属性,name:'mipang',sound:'喵喵喵~~';
// 所以输出是: mipang speak 喵喵喵!!
mipang.speak();

call()、apply()语法

通过上面的例子,我们对上下文有了一个基本概念,此时我们再来讨论call(),apply()
如一开始所说,call()和apply()都是用来改变函数执行时的上下文的,两者的区别是传参方式的不同:

// call()具有多个参数,apply方法只有两个参数;
// 两者的第一个参数都是一个对象obj,用来改变函数function的上下文;
// 即 函数function中的this指向obj对象;

function.call(obj,arg1,arg2,arg3,...);   // 第一个参数后面的参数是一个参数列表
function.apply(obj,[arg1,arg2,arg3,...])  // 第二个参数是一个数组,数组的元素为函数的参数,即将call()方法的参数列表写成数组形式

我们举个例子来说一下call和apply的具体用法:

// 创建对象bajie,bajie有个introduce方法可以用来介绍自己的光辉事迹
var bajie = {
  name:  '猪八戒',
  introduce:  function (job,ability) {
    console.log(job + this.name + ability);
  }
}
bajie.introduce('天蓬大元帅','调戏嫦娥仙子'); //天蓬大元帅猪八戒调戏嫦娥仙子

// 创建对象wukong,wukong并没有一个介绍自己光辉事迹的introduce方法
var wukong = {
  name: '孙悟空'
}

假设我们想让wukong也有办法来介绍自己的光辉事迹,可以给对象wukong添加一个相同的introduce方法
假设我们也想给牛魔王、白骨精、金角大王等等相同的能力,难道要分别给每一个创建这个方法吗?当然不是,这个时候call(),apply()就派上用场了:

bajie.introduce.call(wukong,'齐天大圣','调戏嫂嫂铁扇公主');
bajie.introduce.apply(wukong,['齐天大圣','调戏嫂嫂铁扇公主']);
// 齐天大圣孙悟空调戏嫂嫂铁扇公主

我们来看一个实际应用场景:

function Animal(name,food,sound){
  this.name = name;
  this.food = food;
  this.sound = sound;
}
Animal.prototype.speak = function() {
  console.log(this.name+'爱吃'+this.food+'    '+this.sound);
}
function Cat(name,food,sound) {
  // Animal.call(this,name,food,sound);
  Animal.apply(this,arguments);
}
Cat.prototype = new Animal();
var cat = new Cat('咪胖','鱼','喵喵喵~');
cat.speak();   // 咪胖爱吃鱼    喵喵喵~

apply()方法特性:

apply方法会将默认将参数数组转换为参数列表,利用这一特性,有下面几个应用:

  1. 数组合并:
var arr1 = [1,2,3];
var arr2 = [4,5,6];
// 因为push()方法只接受参数列表,利用apply的特性将数组参数转为参数列表
arr1.push.apply(arr1,arr2);
// 或者Array.prototype.push.apply(arr1,arr2);
console.log(arr1);  // [1,2,3,4,5,6]
// 该方法接受参数列表,并将参数列表转为数组返回
function transtoArray(){
  var values = new Array();
  values.push.apply(values,arguments);
  return values;
}

var arr = transtoArray('张三','李四','王五','赵六');
console.log(arr);   // ['张三','李四','王五','赵六']
  1. 求的数组中的最大值和最小值
var arr = [1,8,5,4,5,9,6,3,7];
var maxValue = Math.max.apply(null,arr);
console.log(maxValue);   // 9
var minValue = Math.min.apply(null,arr);
console.log(minValue);   // 1
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容