亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

js中bind、call、apply函數的用法

2019-11-06 09:44:03
字體:
來源:轉載
供稿:網友

最近一直在用 js 寫游戲服務器,我也接觸 js 時間不長,大學的時候用 js 做過一個 H3C 的 web 的項目,然后在騰訊實習的時候用 js 寫過一些奇怪的程序,自己也用 js 寫過幾個的網站。但真正大規模的使用 js 這還是第一次。我也是初生牛犢不怕虎,這次服務器居然拋棄 C++ 和 lua 的正統搭配,而嘗試用 nodejs 來寫游戲服務器,折騰的自己要死要活的我也是醉了。

在給我們項目組的其他程序介紹 js 的時候,我準備了很多的內容,但看起來效果不大,果然光講還是不行的,必須動手。前幾天有人問我關于代碼里 call() 函數的用法,我讓他去看書,這里推薦用 js 寫服務器的程序猿看 《javascript編程精粹》 這本書,crockford大神果然不是蓋的。之后我在 segmentfault 上又看到了類似的問題,那邊解答之后干脆這里記一筆。

首先,關于 js 定義類或對象的方法,請參看 vevb 的這里,寫的非常詳細和清晰,我不再贅言了。

為了介紹 bind、call、apply 這三個函數的用法,不得不介紹 js 里函數的一些設定。關于這部分推薦通讀 《Javascript編程精粹》 的第四章,這里我所說的在書里都能找到。

關于這三個函數的詳細介紹,可以參看 MDN 的文檔:bind、call、apply。

下面開始搬磚,修改自我之前在 segmentfault 上的答案:

js 里函數調用有 4 種模式:方法調用、正常函數調用、構造器函數調用、apply/call 調用。同時,無論哪種函數調用除了你聲明時定義的形參外,還會自動添加 2 個形參,分別是 this 和 arguments。arguments 不涉及到上述 3 個函數,所以這里只談 this。this 的值,在上面 4 中調用模式下,分別會綁定不同的值。分別來說一說:方法調用:這個很好理解,函數是一個對象的屬性,比如

1234567var a = {        v : 0,        f : function(xx) {                        this.v = xx;        }}a.f(5);

這個時候,上面函數里的 this 就綁定的是這個對象 a。所以 this.v 可以取到對象 a 的屬性 v。

正常函數調用:依然看代碼

1234function f(xx) {            this.x = xx;}f(5);

這個時候,函數 f 里的 this 綁定的是全局對象,如果是在瀏覽器運行的解釋器中,一般來說是 window 對象。所以這里 this.x 訪問的其實是 window.x ,當然,如果 window 沒有 x 屬性,那么你這么一寫,按照 js 的坑爹語法,就是給 window 對象添加了一個 x 屬性,同時賦值。

構造器函數調用:構造函數一直是我認為是 js 里最坑爹的部分,因為它和 js 最初設計的基于原型的面向對象實現方式格格不入,就好像是特意為了迎合大家已經被其他基于類的面相對象實現給慣壞了的習慣。如果你在一個函數前面帶上 new 關鍵字來調用,那么 js 會創建一個 PRototype 屬性是此函數的一個新對象,同時在調用這個函數的時候,把 this 綁定到這個新對象上。當然 new 關鍵字也會改變 return 語句的行為,不過這里就不談了??创a

1234function a(xx) {            this.m = xx;}var b = new a(5);

上面這個函數和正常調用的函數寫法上沒什么區別,只不過在調用的時候函數名前面加了關鍵字 new 罷了,這么一來,this 綁定的就不再是前面講到的全局對象了,而是這里說的創建的新對象,所以說這種方式其實很危險,因為光看函數,你不會知道這個函數到底是準備拿來當構造函數用的,還是一般函數用的。所以我們可以看到,在 jslint 里,它會要求你寫的所有構造函數,也就是一旦它發現你用了 new 關鍵字,那么后面那個函數的首字母必須大寫,這樣通過函數首字母大寫的方式來區分,我個人只有一個看法:坑爹:)

apply/call 調用:我們知道,在 js 里,函數其實也是一個對象,那么函數自然也可以擁有它自己的方法,有點繞,在 js 里,每個函數都有一個公共的 prototype —— Function,而這個原型自帶有好幾個屬性和方法,其中就有這里困惑的 bind、call、apply 方法。先說 apply 方法,它讓我們構造一個參數數組傳遞給函數,同時可以自己來設置 this 的值,這就是它最強大的地方,上面的 3 種函數調用方式,你可以看到,this 都是自動綁定的,沒辦法由你來設,當你想設的時候,就可以用 apply() 了。apply 函數接收 2 個參數,第一個是傳遞給這個函數用來綁定 this 的值,第二個是一個參數數組。看代碼

1234567function a(xx) {            this.b = xx;}var o = {};a.apply(o, [5]);alert(a.b);    // undefinedalert(o.b);    // 5

是不是很神奇,函數 a 居然可以給 o 加屬性值。當然,如果你 apply 的第一個參數傳遞 null,那么在函數 a 里面 this 指針依然會綁定全局對象。

call() 方法和 apply() 方法很類似,它們的存在都是為了改變 this 的綁定,那 call() 和 apply() 有什么區別呢?就我個人看來,沒啥鳥區別。。。開玩笑!剛剛說了,上面 apply() 接收兩個參數,第一個是綁定 this 的值,第二個是一個參數數組,注意它是一個數組,你想傳遞給這個函數的所有參數都放在數組里,然后 apply() 函數會在調用函數時自動幫你把數組展開。而 call() 呢,它的第一個參數也是綁定給 this 的值,但是后面接受的是不定參數,而不再是一個數組,也就是說你可以像平時給函數傳參那樣把這些參數一個一個傳遞。所以如果一定要說有什么區別的話,看起來是這樣的

1234567function a(xx, yy) {        alert(xx, yy);        alert(this);        alert(arguments);}a.apply(null, [5, 55]);a.call(null, 5, 55);

僅此而已。

最后再來說 bind() 函數,上面講的無論是 call() 也好, apply() 也好,都是立馬就調用了對應的函數,而 bind() 不會, bind() 會生成一個新的函數,bind() 函數的參數跟 call() 一致,第一個參數也是綁定 this 的值,后面接受傳遞給函數的不定參數。 bind() 生成的新函數返回后,你想什么時候調就什么時候調,看下代碼就明白了

12345678910var m = {       "x" : 1};function foo(y) {    alert(this.x + y);}foo.apply(m, [5]);foo.call(m, 5);var foo1 = foo.bind(m, 5);foo1();

末了來個吐槽,你在 js 里想定義一個函數,于是你會這么寫:

1function jam() {};

其實這是 js 里的一種語法糖,它等價于:

1var jam = function() {};

然后你想執行這個函數,腦洞大開的你會這么寫:

1function jam() {}();

但是這么寫就報錯了,其實這種寫法也不算錯,因為它確實是 js 支持的函數表達式,但是同時 js 又規定以 function 開頭的語句被認為是函數語句,而函數語句后面是肯定不會帶 () 的,所以才報錯,于是聰明的人想出來,加上一對括號就可以了。于是就變成了這樣:

1(function jam() {}());

這樣就定義了一個函數同時也執行它,詳情參見 ECMAScript 的 Expression Statement 章節。

本文出自 “菜鳥浮出水” 博客,請務必保留此出處http://rangercyh.blog.51cto.com/1444712/1615809


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91亚洲va在线va天堂va国| 欧美高清视频免费观看| 中文字幕日韩av综合精品| 亚洲国产精品成人av| 国内精品一区二区三区四区| 最新国产成人av网站网址麻豆| 2019国产精品自在线拍国产不卡| 亚洲成人激情小说| 91精品国产91久久久久久最新| 欧美日韩xxx| 亚洲一品av免费观看| 亚洲一品av免费观看| 国产精品吹潮在线观看| 日韩电影在线观看永久视频免费网站| 亚洲精品一区二区三区不| 精品日韩视频在线观看| 久久全国免费视频| 亚洲裸体xxxx| 国产精品久久久久久久久久99| 国产视频精品久久久| 久久久女女女女999久久| 国产亚洲精品美女久久久久| 91成人福利在线| 亚洲免费精彩视频| 欧美成人黄色小视频| 国产区亚洲区欧美区| 日本欧美国产在线| 8090成年在线看片午夜| 亚洲精品国产品国语在线| 91国语精品自产拍在线观看性色| 色综合久综合久久综合久鬼88| 国产日韩在线免费| 91久久国产精品| 午夜精品福利在线观看| 亚洲精品网站在线播放gif| 成人a视频在线观看| 亚洲日韩中文字幕| 成人国产精品色哟哟| 亚洲新声在线观看| 色偷偷91综合久久噜噜| 欧美性xxxxx| 在线播放亚洲激情| 国产精品美女久久久久久免费| 国产在线观看一区二区三区| 欧美一级成年大片在线观看| 欧美一级淫片播放口| 国产午夜精品全部视频播放| 日本欧美国产在线| 91国产视频在线播放| 久久视频中文字幕| 最近2019中文字幕大全第二页| 中文字幕亚洲综合久久| 精品国模在线视频| 欧美性在线观看| 精品国产欧美成人夜夜嗨| 中国china体内裑精亚洲片| 欧美老少做受xxxx高潮| 久久精品成人欧美大片古装| 国产精品久久色| 亚洲欧美国产日韩天堂区| 亚洲精品国产精品国自产在线| 欧美精品久久久久久久| 亚洲欧美日韩中文在线| 国产精品高清免费在线观看| 性亚洲最疯狂xxxx高清| 成人深夜直播免费观看| 亚洲国产一区二区三区四区| 亚洲欧美日韩一区二区在线| 日韩av手机在线看| 最新91在线视频| 亚洲国产女人aaa毛片在线| 亚洲中国色老太| www.久久久久久.com| 国产精品欧美激情在线播放| 精品日本高清在线播放| 岛国精品视频在线播放| 久久久久99精品久久久久| 亚洲tv在线观看| 国产精品免费观看在线| 精品久久久av| 亚洲精品色婷婷福利天堂| 欧美日韩成人在线观看| 日韩av在线播放资源| 97av在线视频免费播放| 亚洲最大的免费| 久久久免费观看| 精品久久久久久久久久| 亚洲伊人一本大道中文字幕| 在线观看欧美日韩| 欧美成人激情图片网| 性欧美亚洲xxxx乳在线观看| 色天天综合狠狠色| 国产视频久久久久久久| 亚洲第一区在线观看| 国产精品久久久久999| 亚洲电影第1页| 亚洲一区999| www.日韩欧美| 欧美日韩性生活视频| 久久久久久久一| 亚洲一区二区三区在线视频| 2021久久精品国产99国产精品| 久久香蕉精品香蕉| 国产精品亚洲自拍| 欧美大片大片在线播放| 成人亚洲欧美一区二区三区| 欧美精品激情在线| 日韩免费在线视频| 亚洲精品欧美极品| 色婷婷综合成人| 播播国产欧美激情| 亚洲男人第一av网站| 欧美成人第一页| 日韩精品中文字幕视频在线| 红桃视频成人在线观看| 69久久夜色精品国产7777| 欧美日韩ab片| 日韩av中文字幕在线免费观看| 亚洲专区国产精品| 久久精品亚洲国产| 色哟哟网站入口亚洲精品| 欧美成人精品一区二区| 久久人人97超碰精品888| 国产激情久久久久| 性色av一区二区三区免费| 最近2019中文免费高清视频观看www99| 国产成人+综合亚洲+天堂| 国产精品久久不能| 欧美另类极品videosbest最新版本| 蜜臀久久99精品久久久无需会员| 日本精品一区二区三区在线播放视频| 国产小视频国产精品| 亚洲aaa激情| 亚洲乱码国产乱码精品精| 91免费精品国偷自产在线| 国产精品第1页| 国产亚洲精品日韩| 国产成人精品a视频一区www| 成人国产精品日本在线| 色综合影院在线| 成人国产精品日本在线| 国产在线观看精品一区二区三区| 欧美成人第一页| 中日韩美女免费视频网站在线观看| xvideos亚洲人网站| 国产香蕉精品视频一区二区三区| 亚洲欧美国产精品| 国产精品999| 亚洲国产另类久久精品| 国产精品一区=区| 最近的2019中文字幕免费一页| 91精品国产亚洲| 97国产精品视频人人做人人爱| 国产在线视频不卡| 日韩av中文字幕在线免费观看| 日韩亚洲一区二区| 亚洲美女性生活视频| 国产欧美日韩中文字幕在线| 欧美老肥婆性猛交视频| 不卡av在线网站| 97在线视频国产| 国产美女91呻吟求| 操日韩av在线电影| 韩国欧美亚洲国产|