js之call、apply方法详解

定义

apply()方法:

Function.apply(obj,args)
obj:这个对象将代替Function类里this对象
args:这个是数组,它将作为参数传给Function(args-->arguments)

call()方法:

Function.call(obj,[param1[,param2[,…[,paramN]]]])
obj:这个对象将代替Function类里this对象
params:这个是一个参数列表

相同点

作用是一样的,call 和 apply 都是为了改变函数体内部 this 的指向,也就是把Function(即this)绑定到obj,这时候obj具备了Function的属性和方法,说白一点就是obj继承了Function的属性和方法。

不同点

相信大家也已经发现了,他们唯一区别就是接受参数的方式不太一样,apply接受的是数组参数,call接受的是连续参数。

方法使用1

function mul(a,b){
    return this+(a*b);
}
//接着我们在控制台上打印出
console.log(mul.call(null,2,3));
console.log(mul.call('s',2,3));
console.log(mul.call(3,2,3));
console.log(mul.apply(null,[2,5]));
console.log(mul.apply(2,[2,5]));

结果

[object Window]6
s6
9
[object Window]10
12

方法使用2

学js的都知道 Math.max()方法,比如有三个参数2,3,4那么我们要找出最大值可以这么写 Math.max(2,3,4) 那要是有 100 个或更多参数呢?这时候就可以结合 apply 和数组轻松实现了。

var arr=[2,3,4,5,6,7,8,9,10,23,45,66,22,11];
console.log(Math.max.apply(null,arr));

方法使用3-----对象继承

function Person(name,age) {
    this.name=name;
    this.age=age;
}

var Student=function(name,age,gender) {
    Person.call(this,name,age);//this继承了person的属性和方法
    this.gender=gender;
}
var student=new Student("王刚", 20, "男");
alert("姓名:"+student.name+"\n"+"年龄:"+student.age+"\n"+"性别:"+student.gender);

输出

姓名:王刚
年龄:20
性别:男

这样用call就实现了继承(用apply也类似)

原理简单解析

我们来看下面示例:

 function fn1() {
       console.log(1);
}
function fn2() {
     console.log(2);
}
fn1.call(fn2);//执行call方法,里面执行fn1,并且让f1函数中的this变成fn2,输出的结果是1
fn1.call.call(fn2);//执行第二个call方法,在这个call方法里面,执行fn1.call,让fn1.call这个方法中的this变成fn2,输出的结果是2

fn1.call(fn2)的结果相信大部分童鞋都明白,fn1.call.call(fn2)的结果似乎出乎你我的意料之外,这是为什么呢?下面就给大家分析下各自产生的结果流程:

fn1.call(fn2)

Function.prototype.call(fn1);//执行call方法,在call方法里面让 Function.prototype执行,并且把Function.prototype中的this改变成fn1
Function.prototype对应的不是一个对象而是一个函数(Empty)

fn1.call.call(fn2)

//第一个call执行:
Function.prototype.call.call(fn2);//执行call方法,在call里面让Function.prototype.call执行,
并且让这个call方法中的this是fn2,其实就是让fn2执行
和我们的fn1.call.call(fn2)一样  Function.prototype.call==fn1.call
//第二个call执行:
 fn1.call(); -->fn1.call这个方法中的this变成fn2
fn1.call获取的是我们Function这个原型上的call方法,也就是让Function原型上的call方法执行,让里面的this变成fn2
[参考下代码]
this(); -->fn2();

fn.call 为啥函数可以调用call这个方法?

Function js中所有的函数数据类型对应的基类 call和apply就是定义在Function这个基类的原型上的,而每一个函数都是Function这个基类的一个实例,所有所有的函数都可以使用call和apply方法

Function.prototype.call = function () {
     call这个方法中的this就是我们的fn1
     1、让fn1执行
      this();
      2、把fn1中的this改变成我们第一个参数传的值
       把this函数中的[this]改变成arguments[0]
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容

  • 注:本文案例环境为非严格模式,严格模式下禁止关键字this指向全局对象 一、方法是怎么执行的? 首先说一下js中方...
    就那ck阅读 1,149评论 5 17
  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,745评论 2 17
  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,145评论 0 13
  • 网上都说产品经理是一个杂家,什么都得知道什么都得懂,所以为了Get这个技能,多多学习准是没错的。微信公众号虽然良莠...
    派派呀派派呀阅读 5,269评论 2 57
  • 让一个类继承另一个类后,可添加区分子类和父类所需的新属性和方法 1、如果一个属性或方法是任何汽车都有的,而...
    陈容喜阅读 422评论 0 0