如何理解js中的call和apply?

大家好,我是IT修真院萌新分院第3期的学员张晓琳,一枚正直、纯洁、善良的前端程序员今天给大家分享一下,修真院官网js任务2深度思考中的知识点——如何理解js中call和apply?

1.背景介绍

call 和 apply 都是为了改变某个函数运行时的 

context 即上下文而存在的,换句话说,

就是为了改变函数体内部 this 的指向。

因为 JavaScript 的函数存在

「定义时上下文」和「运行时上下文」

以及「上下文是可以改变的」这样的概念。

2.知识剖析

1. apply: 

方法能劫持另外一个对象的方法,继承另外一个对象的属性. 

Function.apply(obj,args)方法能接收两个参数

obj:这个对象将代替Function类里this对象

args:这个是数组,它将作为参数传给Function(args-->arguments)

2. call 

和apply的意思一样,只不过是参数列表不一样

Function.call(obj,[param1[,param2[,…[,paramN] ] ] ] )

obj:这个对象将代替Function类里this对象

params:这个是一个参数列表

3.常见问题

如何使用call和apply?

4.解决方案

call 和 apply 的作用基本类似, 

都是去执行function并将这个function 

的context替换成第一个参数带入。 

两者的不同是call 必须将function 的参数一一带入,接受的是连续参数

而 apply 接受的是数组参数 只要在第二个参数带入一个数列。

//控制台运行:

//j  k  形參

function add(j, k) {

    return j + k;

}

function sub(j, k) {

    return j - k;

}

// 5 3  實參

add(5, 3); //8

add.call(sub, 5, 3); //8

add.apply(sub, [5, 3]); //8

sub(5, 3); //2

sub.call(add, 5, 3); //2

sub.apply(add, [5, 3]); //2

//通过call和apply实现对象继承。

var Parent = function () {

    this.name = "yjc";

    this.age = 22;

}

var child = {};

console.log(child);//Object {} ,空对象

Parent.call(child);

console.log(child); //Object {name: "yjc", age: 22}

//call方法1

window.color = 'red';

document.color = 'yellow';

var s1 = {color: 'blue' };

function changeColor(){

    console.log(this.color);

}

//2

changeColor.call();        //red (默认传递参数)

changeColor.call(window);  //red

changeColor.call(document); //yellow

changeColor.call(this);    //red

changeColor.call(s1);      //blue

var Pet = {

    words : '...',

    speak : function (say) {

        console.log(say + ''+ this.words)

}

}

Pet.speak('Speak'); // 结果:Speak...

var Dog = {

    words:'Wang'

}

//将this的指向改变成了Dog

Pet.speak.call(Dog, 'Speak'); //结果:SpeakWang

//apply方法1

window.number = 'one';

document.number = 'two';

var s1 = {number: 'three' };

function changeColor(){

    console.log(this.number);

}

changeColor.apply();        //one (默认传参)

changeColor.apply(window);  //one

changeColor.apply(document); //two

changeColor.apply(this);    //one

changeColor.apply(s1);      //three

//方法2

function Pet(words){

    this.words = words;

    this.speak = function () {

        console.log( this.words)

}

}

function Dog(words){

    //Pet.call(this, words); //结果:Wang

    Pet.apply(this, arguments); //结果:Wang

}

var dog = new Dog('Wang');

dog.speak();

5.编码实战

// call方法可以用来代替另一个对象调用一个方法,

// call方法可以将一个函数的对象上下文从初始的上下文改变为thisObj指定的新对象,

// 如果没有提供thisObj参数,那么Global对象被用于thisObj。

//1:

    function add(c,d){

        return this.a + this.b + c + d;

}

var s = {a:1, b:2};

console.log(add.call(s,3,4)); // 1+2+3+4 = 10

console.log(add.apply(s,[5,6])); // 1+2+5+6 = 14

//2:

window.firstName = "Cynthia";

window.lastName = "_xie";

var myObject = {firstName:'my', lastName:'Object'};

function getName(){

    console.log(this.firstName + this.lastName);

}

function getMessage(sex,age){

    console.log(this.firstName + this.lastName + " 性别: " + sex + " age: " + age );

}

getName.call(window); // Cynthia_xie

getName.call(myObject); // myObject

getName.apply(window); // Cynthia_xie

getName.apply(myObject);// myObject

getMessage.call(window,"女",21); //Cynthia_xie 性别: 女age: 21

getMessage.apply(window,["女",21]); // Cynthia_xie 性别: 女age: 21

getMessage.call(myObject,"未知",22); //myObject 性别: 未知age: 22

getMessage.apply(myObject,["未知",22]); // myObject 性别: 未知 age: 22

6.扩展思考

call()和apply()两种方法的区别? 

相同点:两个方法产生的作用是完全一样的

不同点:方法传递的参数不同

call()接受的是一个参数列表,而apply()接受一个参数数组。

func.call(this, arg1, arg2);

func.apply(this, [arg1, arg2])

其中 this 是你想指定的上下文,他可以是任何一个 JavaScript 对象(JavaScript 中一切皆对象),

call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。

因此要说适用条件的话,当你的参数是明确知道数量时用 call 。

而不确定的时候用 apply,然后把参数 push 进数组传递进去。

7.参考文献

參考

8.更多讨论

问题:

Q1:王姣妍:是call还是apply能改变this的指向?

A1:张晓琳:两个都能改,就是传参数方式不一样呀,apply传数组,call传字符串。

Q2:王栋:apply的应用场景呢??

A2:其他人:

我首先从网上查到关于apply和call的定义,然后用示例来解释这两个方法的意思和如何去用.  

         apply:方法能劫持另外一个对象的方法,继承另外一个对象的属性.  

 Function.apply(obj,args)方法能接收两个参数  

obj:这个对象将代替Function类里this对象  

args:这个是数组,它将作为参数传给Function(args-->arguments)  

         call:和apply的意思一样,只不过是参数列表不一样.  

 Function.call(obj,[param1[,param2[,…[,paramN]]]])  

obj:这个对象将代替Function类里this对象  

params:这个是一个参数列表  

1.apply示例:  

/*定义一个人类*/   

function Person(name,age) {   

this.name=name; this.age=age;   

}   

/*定义一个学生类*/   

functionStudent(name,age,grade) {   

Person.apply(this,arguments); this.grade=grade;   

}   

//创建一个学生类   

var student=new Student("qian",21,"一年级");   

//测试   

alert("name:"+student.name+"\n"+"age:"+student.age+"\n"+"grade:"+student.grade);   

//大家可以看到测试结果name:qian age:21 grade:一年级   

//学生类里面我没有给name和age属性赋值啊,为什么又存在这两个属性的值呢,这个就是apply的神奇之处.   

分析: Person.apply(this,arguments);  

this:在创建对象在这个时候代表的是student  

arguments:是一个数组,也就是[“qian”,”21”,”一年级”];  

也就是通俗一点讲就是:用student去执行Person这个类里面的内容,在Person这个类里面存在this.name等之类的语句,这样就将属性创建到了student对象里面 

Q3:王栋:call的应用场景呢??

A3:其他人:在给对象参数的情况下,如果参数的形式是数组的时候,比如apply示例里面传递了参数arguments,这个参数是数组类型,并且在调用Person的时候参数的列表是对应一致的(也就是Person和Student的参数列表前两位是一致的) 就可以采用 apply , 如果我的Person的参数列表是这样的(age,name),而Student的参数列表是(name,age,grade),这样就可以用call来实现了,也就是直接指定参数列表对应值的位置(Person.call(this,age,name,grade)); 

PPT

如何理解js中call和apply视频


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

推荐阅读更多精彩内容

  • 大家好,我是IT修真院深圳分院第01期学员,一枚正直纯洁善良的web程序员。 今天给大家分享一下,修真院官网JS任...
    嘴角那抹温柔阅读 367评论 0 0
  • 1.背景介绍 call和apply都是为了改变某个函数运行时的context即上下文而存在的,换句话说,就是为了改...
    远望的云阅读 568评论 0 1
  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,717评论 2 17
  • 单例模式 适用场景:可能会在场景中使用到对象,但只有一个实例,加载时并不主动创建,需要时才创建 最常见的单例模式,...
    Obeing阅读 2,054评论 1 10
  • 晚上番茄籽在隔壁邻居家玩,旁边两个姐姐在下跳棋,这是小家伙第一次见这玩意儿,我就问他:“姐姐在做什么呀?”因为真的...
    沙格西矛阅读 220评论 0 0