从call、apply、bind引发的思考

这段时间一直看JavaScript高级程序设计,然后就翻到call、apply、bind的介绍,突然有“社交恐惧症”感,不太想打招呼。可我既然买来这本书,还立志要成为一个优(zhuang)秀(bi)的前端开发者,可不能被这些屈服了啊~

6af89bc8gw1f8ub3qow2tj203902gq2x.jpg

要知道call、apply、bind对很多人来说是一个比较晦涩的用法,包括我,以前很多次看到这个,甚至常出现在面试题,但我觉得这些太晦涩的,就选择视而不见的。正如“今天你对我爱理不理,明天我让你高攀不起”这句话,捂脸ing,但我一定要高攀得起(会打自己的脸么)好啦,该正经了~

6af89bc8gw1f8t5k9h5tzj20jg0hrdgm.jpg

this

要理解call、apply、bind,首先要知道this。书上是这样介绍的:

this引用的是函数执行的环境对象(当在网页的全局作用域中调用函数时,this对象引用的就是window)

好比说我有一个函数,谁拿我的函数来调用,我就认谁当爸爸,爸爸就是this。我们来看看例子:

例1:

window.name="window";
function fun(){
    let name="I am fun";
    console.log(this.name);
}
fun(); //window

打印出“window”,而不是“I am fun”,为什么呢?关键在于 <font color="#dd0000">this</font>,因为fun()被调用的是全局对象window,所以this指向window,然后window的name的值就是“window”,所以打印出<font color="#dd0000">window</font>~然后我们再小小的改动下,看例2

例2:

window.name="window";
function fun(){
    this.name="I am fun";
    console.log(this.name);
}
fun(); //I am fun

把 <font color="#dd0000">let</font> 改成 <font color="#dd0000">this.</font>,此时this就是指向window,而window也有name的属性,就被this.name的值覆盖了,所以打印出<font color="#dd0000">I am fun</font>~

这就是全局作用域调用函数的说法,然后我们来看看对象调用函数,什么叫对象调用函数,首先要知道什么叫对象,有基础的人应该知道了叭,下面我们来看看例子:

例1:

window.name="window";
let obj={
    name:'obj'
};//这就是对象
function fun(){
    console.log(this.name);
}
obj.fun=fun;
obj.fun(); //obj

建立一个obj对象,有一个属性name,然后把全局的fun函数指向obj,注意这里并没有加(),因为如果加()就是全局对象直接调用函数,自己可以试试。指向obj后,这就相当于

obj={
    name:'obj',
    fun:function(){
        console.log(this.name);//obj
    }
}

此时this就是obj,而obj的name是obj,所以打印出 <font color="#dd0000">obj</font>~

假如obj没有name,会怎样呢?
例2:

obj={
    // name:'obj',
    fun:function(){
        console.log(this.name);
    }
}
obj.fun();//undefined

this仍然指向obj,而obj没有name的属性,所以打印出 <font color="#dd0000">undefined</font>~

这下可以明白了this的作用叭,还是不明白的话,看来我还得提高文笔水平和表达能力~没明白的话,文章结尾会献出参考链接,有些人写的比我好~

Unknown.jpg

apply、call、bind

看到这个,别觉得头疼哈~别以为了有了es6,就不用这些了。毕竟我们中国使用的技术情况,你懂的~apply、call、bind的作用就是改变this,嗯,怎么讲呢?先看看书上的说法~

用途都是在特定的作用域中调用函数,实际上等于<font color="#dd0000">设置函数体内this对象的值</font>

就好比说一个导游(touristGuide)有一个旅游的计划,但只有静安寺,然后旅者(traveller)不想去静安寺,就想去城隍庙,在js上一般做法的就是再建立一个新的对象,名字改为“城隍庙”,这不是累死导游么?这时候apply、call就用上了,在原本上的计划(必须在函数上,因为函数才具有apply、call的属性),引用旅者的对象,this就指向旅者想要的地方,这就可以了,导游表示爽歪歪的,下面看看例子:

例1:

let toristGuide={
    name:'静安寺',
    fun:function(){
        console.log('要去的地方:'+this.name);
    }
}
let traveller={
    name:'城隍庙',
}
toristGuide.fun();//"要去的地方:静安寺"
toristGuide.fun.apply(traveller);//“要去的地方:城隍庙”

touristGuide.fun()中的this指向自己(就是toristGuide本身),所以才会打印出<font color="#dd0000">静安寺</font>,然后用apply,this的指向就发生变化,改为指向traveller对象,而traveller的name是“城隍庙”,所以才会打印出<font color="#dd0000">城隍庙</font>

然后我们再小小的改下,如果旅者没说明要去哪儿:
例2:

let toristGuide={
    name:'静安寺',
    fun:function(){
        console.log('要去的地方:'+this.name);
    }
}
let traveller={
}
toristGuide.fun();//"要去的地方:静安寺"
toristGuide.fun.apply(traveller);//要去的地方:undefined

嘿,即使旅者没说啥,也会根据旅者的打印出<font color="#dd0000">undefined</font>,毕竟“顾客为上”

apply和call作用一样,就是接受的第二个参数不同

apply

接受两个参数,第一个参数是在其中运行函数的作用域,第二个参数是数组,也可以是arguments对象,看例子,根据上面的例子改动下,加个参数:
例1:

let toristGuide={
    name:'静安寺',
    fun:function(a,b){
        console.log('想要做什么:'+a,b);
    }
}
let traveller={
    name:'城隍庙',
}
toristGuide.fun('吃','玩');//想要做什么:吃,玩
toristGuide.fun.apply(traveller,['拍照','吃美食']);//想要做什么:拍照,吃美食

call

第一个参数和上面的一样,而第二个参数不同,就是直接传递给函数,看下面的例子:
例1:

let toristGuide={
    name:'静安寺',
    fun:function(a,b){
        console.log('想要做什么:'+a,b);
    }
}
let traveller={
    name:'城隍庙',
}
toristGuide.fun('吃','玩');//想要做什么:吃,玩
toristGuide.fun.call(traveller,'拍照','吃美食');//想要做什么:拍照,吃美食

bind

bind和上面用途一样的,也是改变this的指向,但用法不一样的,书上的说法是:

这个方法会创建一个函数

嗯,好像不太理解的,看例子:

例1:

let toristGuide={
    name:'静安寺',
    fun:function(a,b){
        console.log('想要做什么:'+a,b);
    }
}
let traveller={
    name:'城隍庙',
}
toristGuide.fun.bind(traveller,'拍照','吃美食');

改为bind后,结果没打印出什么的,反而是打印出函数体,然后根据书上的说法和例子,就加上个()

toristGuide.fun.bind(traveller,'拍照','吃美食')();//想要做什么:拍照,吃美食

这才恍然大悟,原来这就是用法的。

这就是apply、call、bind的用法,童鞋们可能看就懂的,但自己做起来却觉得困惑的,我只能说多看多做,就熟能生巧了,祝早日征服这些~(手动滑稽)

到此为止了,好累呀~求点赞~

献上参考链接:
1、https://juejin.im/post/59bfe84351882531b730bac2#heading-0 这个比较详细的,不懂的话,可以再看看这个
2、https://www.cnblogs.com/coco1s/p/4833199.html

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

推荐阅读更多精彩内容