2020-07-09avaScript 中 call()瑰枫、apply()、bind() 的用法

例一

            var name = '小王',
                age = 17;
            var obj = {
                name: "小張",
                thisCopy: this, //this指向 window
                objAge: this.age, //this指向window
                myFun: function() {
                    console.log("obj-this", this) //this指向obj,obj沒有age這個(gè)屬性
                    // console.log(this.name + "年齡" + this.age)
                }
            }
            console.log(obj)
            console.log(this.age);//這個(gè)this指向window
            console.log(obj.objAge) //17
            obj.myFun(); //小張年齡 undefined

例2

            var fav = "盲僧"
            function shows() {
                //console.log("shows-this", this) //this指向window
                console.log(this.fav)
            }
            shows() //盲僧

比較一下這兩者 this 的差別展姐,第一個(gè)打印里面的 this 指向 obj躁垛,第二個(gè)全局聲明的 shows() 函數(shù) this 是指向window ;

1圾笨,call()教馆、apply()、bind() 都是用來重定義 this 這個(gè)對(duì)象的擂达!
            var name = '小王',
                age = 17;
                var obj = {
                    name: "小張",
                    objAge: this.age,
                    myFun: function() {
                        console.log("obj-this", this) //this指向obj
                        console.log(this.name + "年齡" + this.age)
                          }
                      }
            var db = {
                name: "德瑪",
                age: "89"
            }
            obj.myFun();//小張年齡underfind  myFun的this指向obj
            var myFunA= obj.myFun;
            //myFunA在外部調(diào)用土铺,此時(shí)的this指向了全局對(duì)象
            myFunA();//小王年齡17
             //為了保證this指向不變,我們可以通過bind方法綁定this指向
            //如:
            var myFunA2= obj.myFun.bind(obj);
            console.log(myFunA2()); //小張年齡underfind 需要調(diào)用才執(zhí)行
            //此時(shí)可以看到this的指向保持指向了obj這個(gè)對(duì)象。

            var myFunA3 = obj.myFun.call(obj);
            console.log(myFunA3 ); //小張年齡underfind 不需要調(diào)用就執(zhí)行
            var myFunA4 = obj.myFun.apply(obj);
            console.log(myFunA4); //小張年齡underfind 不需要調(diào)用就執(zhí)行
            //此時(shí)你會(huì)發(fā)現(xiàn)當(dāng)我們用call或者apply方法來保證this指向的時(shí)候悲敷,
           //call和apply方法會(huì)直接執(zhí)行掉myFun這個(gè)方法究恤,不需要調(diào)用。


            //obj.myFun方法里的this由obj指向db
            obj.myFun.call(db) // 德瑪年齡 89
            obj.myFun.apply(db) // 德瑪年齡 89

            console.log(obj.myFun.bind(db)) //bind 返回的是一個(gè)新的函數(shù)后德,你必須調(diào)用它才會(huì)被執(zhí)行部宿。
            obj.myFun.bind(db)() //調(diào)用bind返回的函數(shù) // 德瑪年齡 89

以上出了 bind 方法后面多了個(gè) () 外 ,結(jié)果返回都一致瓢湃!
由此得出結(jié)論理张,bind和call,apply的區(qū)別绵患,bind 返回的是一個(gè)新的函數(shù)雾叭,.只會(huì)改變函數(shù)this指向不會(huì)執(zhí)行函數(shù),你必須調(diào)用它才會(huì)被執(zhí)行落蝙,call和apply會(huì)改變this指向并且直接執(zhí)行了函數(shù)

2织狐,對(duì)比call 、bind 筏勒、 apply 傳參情況下
            var name = '小王',
                age = 17;
            var obj = {
                name: "小張",
                objAge: this.age,
                myFun: function(fm, ft) {
                    console.log("obj-this", this) //this指向obj
                    console.log(this.name + "年齡" + this.age, " 來自 " + fm + " 去往  " + ft)
                }
            }
            var db = {
                name: "德瑪",
                age: "89"
            }

            obj.myFun.call(db, "廣州", "深圳") //德瑪年齡89  來自 廣州 去往  深圳
            obj.myFun.apply(db, ["廣州", "深圳"]) // 德瑪年齡89  來自 廣州 去往  深圳

            obj.myFun.bind(db, "廣州", "深圳")() //德瑪年齡89  來自 廣州 去往  深圳
            obj.myFun.bind(db, ["廣州", "深圳"])() //德瑪年齡89  來自 廣州,深圳 去往  undefined
            //例2
            var obj = {
                a:2,
                sum:function(b,c){
                    return this.a + b + c;
                }
            }

            var sum0 = obj.sum;

           //分別用bind移迫,call,apply方法來調(diào)用sum0方法管行。
           var sum1 = sum0.bind(obj,2,3);
           console.log(sum1()); // 7

           var sum2 = sum0.call(obj,2,3);
           console.log(sum2); // 7

           var sum3 = sum0.apply(obj,[2,3]);
           console.log(sum3); // 7

    從這里我們可以看出bind和call方法傳入?yún)?shù)方式和apply方式不一樣起意。

// 微妙的差距!
//
// 從上面四個(gè)結(jié)果不難看出:
//
// call 病瞳、bind 、 apply 這三個(gè)函數(shù)的第一個(gè)參數(shù)都是 this 的指向?qū)ο蟊幔诙€(gè)參數(shù)差別就來了:
//
// call 的參數(shù)是直接放進(jìn)去的套菜,第二第三第 n 個(gè)參數(shù)全都用逗號(hào)分隔,直接放到后面 obj.myFun.call(db,'成都', ... ,'string' )设易。
//
// apply 的所有參數(shù)都必須放在一個(gè)數(shù)組里面?zhèn)鬟M(jìn)去 obj.myFun.apply(db,['成都', ..., 'string' ])逗柴。
//
// bind 除了返回是函數(shù)以外,它 的參數(shù)和 call 一樣顿肺。
//
// 當(dāng)然戏溺,三者的參數(shù)不限定是 string 類型,允許是各種類型屠尊,包括函數(shù) 旷祸、 object 等等!
總結(jié):
call和bind方法可以傳入多個(gè)參數(shù)讼昆,第二個(gè)參數(shù)后的所有參數(shù)都傳入調(diào)用的函數(shù)中托享,apply方法只能傳入兩個(gè)參數(shù),且第二參數(shù)為數(shù)組,數(shù)組里面的元素傳入到調(diào)用的函數(shù)中闰围。

最后赃绊,我們考慮一下,如果使用apply方法時(shí)羡榴,傳入的第一個(gè)參數(shù)是null時(shí)碧查,調(diào)用函數(shù)時(shí),會(huì)發(fā)生什么情況校仑,會(huì)不會(huì)報(bào)錯(cuò)呢忠售!
不多說,直接上例子

var A={
    name:"我是小A",
    fun:function(num,money){
        console.log("大家好肤视! "+this.name+" 我有"+num+"張"+money+"塊")
    }
}

var B = {
    name:"我是小B"
}
var monies = [10,20];
name="我是小C"

A.fun.apply(null,monies);    //大家好档痪! 我是小C 我有10張20塊

可以看到 如果第一傳入的參數(shù)是null的話,在函數(shù)提內(nèi)的this會(huì)指向全局對(duì)象邢滑,在瀏覽器中就是window腐螟。

所以可以總結(jié)出兩點(diǎn):

1.如果函數(shù)中有明確使用this,那么this就會(huì)指向傳入的第一個(gè)參數(shù)的作用域困后。

2.如果傳入的第一參數(shù)為null時(shí)乐纸,this就會(huì)指向全局的作用域。

fn.apply(this, arguments)將函數(shù)的屬性與方法進(jìn)行拷貝摇予,bai主要是實(shí)現(xiàn)類的繼承汽绢。
            function Person(name) {
                this.name = name;
                console.log('Person',this) //這里的this指向xiaoming這個(gè)實(shí)例
                this.sayname = function() {
                    console.log(this.name) //小明
                }
            }

            function Student(name) {
                console.log("arguments",arguments);//arguments 是函數(shù)參數(shù)組成的一個(gè)數(shù)組,類數(shù)組
                console.log('Student',this) //這里的this指向Student這個(gè)實(shí)例
                //apply將Person方法里的this指向由window指向xiaoming這個(gè)實(shí)例侧戴,并且直接執(zhí)行
                Person.apply(this, arguments); //調(diào)用person并且把this指向Student宁昭,同時(shí)把Student的參數(shù)傳過去,arguments是一個(gè)數(shù)組來的
            }

            var xiaoming = new Student("小明");
            xiaoming.sayname();
            //這樣Student類拷貝了Person的屬性和方法酗宋,實(shí)現(xiàn)了類的繼承
            //忘記加上new命令,函數(shù)里面的this指向了全局作用域

部分轉(zhuǎn)自:https://www.runoob.com/w3cnote/js-call-apply-bind.html

js中arguments詳解

微信圖片_20200724110937.png

一积仗、簡(jiǎn)介

了解arguments這個(gè)對(duì)象之前先來認(rèn)識(shí)一下javascript的一些功能:
其實(shí)Javascript并沒有重載函數(shù)的功能,但是Arguments對(duì)象能夠模擬重載蜕猫。Javascrip中每個(gè)函數(shù)都會(huì)有一個(gè)Arguments對(duì)象實(shí)例arguments寂曹,它引用著函數(shù)的實(shí)參,可以用數(shù)組下標(biāo)的方式"[]"引用arguments的元素回右。arguments.length為函數(shù)實(shí)參個(gè)數(shù)隆圆,arguments.callee引用函數(shù)自身。


微信圖片_20200724111553.png
微信圖片_20200724111558.png

三翔烁、使用方法
雖然arguments對(duì)象并不是一個(gè)數(shù)組(類數(shù)組)渺氧,但是訪問單個(gè)參數(shù)的方式與訪問數(shù)組元素的方式相同

例如:
arguments[0],arguments[1],。租漂。阶女。arguments[n]颊糜; 在js中 不需要明確指出參數(shù)名,就能訪問它們

例如:

function test() {
        var s = "";
        for (var i = 0; i < arguments.length; i++) {
            alert(arguments[i]);
            s += arguments[i] + ",";
        }
        return s;
}
test("name", "age");

輸出結(jié)果:
name,age

我們知道每一個(gè)對(duì)象都有自己的屬性秃踩,arguments對(duì)象也不例外衬鱼,首先arguments的訪問猶如Array對(duì)象一樣,用0到arguments.length-1來枚舉每一個(gè)元素憔杨。下面我們來看看callee屬性鸟赫,返回正被執(zhí)行的** Function** 對(duì)象,guments.callee就是函數(shù)自身消别。,實(shí)現(xiàn)匿名的遞歸函數(shù)抛蚤。代碼如下:

var sum = function (n) {
        if (1 == n) {
            return 1;
        } else {
            return n + arguments.callee(n - 1); //6 5 4 3 2 1
        }
   }
   alert(sum(6));

輸出結(jié)果:21

傳多個(gè)參數(shù)事可以直接用argument,比如求最大值:

function max() {
        var max = arguments[0];
        console.log(arguments)

        for (val of arguments) {
            if (val >= max) {
                max = val;
            }
        }
        return max;
    }
    var maxValue = max('9', 1, 2, 4)
    console.log(maxValue)

     //apply的另一種用法就是用于將數(shù)組分割為一個(gè)個(gè)元素寻狂。
     //例如想在數(shù)組中a[1,2,3,4]中尋找出最大的袁術(shù)出來岁经。
    //利用apply求最大值:
    var a = [1, 2, 3, 4];
    console.log(Math.max(a))
    console.log(Math.max.apply(null, a)); //輸出4)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蛇券,隨后出現(xiàn)的幾起案子缀壤,更是在濱河造成了極大的恐慌,老刑警劉巖纠亚,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件塘慕,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡蒂胞,警方通過查閱死者的電腦和手機(jī)图呢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來骗随,“玉大人蛤织,你說我怎么就攤上這事『枞荆” “怎么了瞳筏?”我有些...
    開封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)牡昆。 經(jīng)常有香客問我,道長(zhǎng)摊欠,這世上最難降的妖魔是什么丢烘? 我笑而不...
    開封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮些椒,結(jié)果婚禮上播瞳,老公的妹妹穿的比我還像新娘。我一直安慰自己免糕,他們只是感情好赢乓,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開白布忧侧。 她就那樣靜靜地躺著,像睡著了一般牌芋。 火紅的嫁衣襯著肌膚如雪蚓炬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天躺屁,我揣著相機(jī)與錄音肯夏,去河邊找鬼。 笑死犀暑,一個(gè)胖子當(dāng)著我的面吹牛驯击,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播耐亏,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼徊都,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了广辰?” 一聲冷哼從身側(cè)響起暇矫,我...
    開封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎轨域,沒想到半個(gè)月后袱耽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡干发,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年朱巨,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片枉长。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡冀续,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出必峰,到底是詐尸還是另有隱情洪唐,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布吼蚁,位于F島的核電站凭需,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏肝匆。R本人自食惡果不足惜粒蜈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望旗国。 院中可真熱鬧枯怖,春花似錦、人聲如沸能曾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至蕊程,卻和暖如春椒袍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背存捺。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工槐沼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人捌治。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓岗钩,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親肖油。 傳聞我的和親對(duì)象是個(gè)殘疾皇子兼吓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355