成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

【博文推薦】Javascript中bind、call、apply函數(shù)用法

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

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

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

javascript中bind、call、apply函數(shù)的用法

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

關于這三個函數(shù)的詳細介紹,可以參看 MDN 的文檔:bindcallapply

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

js 里函數(shù)調用有 4 種模式:方法調用、正常函數(shù)調用、構造器函數(shù)調用、apply/call 調用。

同時,無論哪種函數(shù)調用除了你聲明時定義的形參外,還會自動添加 2 個形參,分別是 this 和arguments。

arguments 不涉及到上述 3 個函數(shù),所以這里只談 this。this 的值,在上面 4 中調用模式下,分別會綁定不同的值。分別來說一說:

方法調用:

這個很好理解,函數(shù)是一個對象的屬性,比如

  1. var a = {     
  2.     v : 0,     
  3.     f : function(xx) {                 
  4.         this.v = xx;     
  5.     } 
  6. a.f(5); 

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

正常函數(shù)調用:依然看代碼

  1. function f(xx) {         
  2.     this.x = xx; 
  3. f(5); 

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

構造器函數(shù)調用:

構造函數(shù)一直是我認為是 js 里最坑爹的部分,因為它和 js 最初設計的基于原型的面向對象實現(xiàn)方式格格不入,就好像是特意為了迎合大家已經(jīng)被其他基于類的面相對象實現(xiàn)給慣壞了的習慣。

如果你在一個函數(shù)前面帶上 new 關鍵字來調用,那么 js 會創(chuàng)建一個 prototype 屬性是此函數(shù)的一個新對象,同時在調用這個函數(shù)的時候,把 this 綁定到這個新對象上。當然 new 關鍵字也會改變return 語句的行為,不過這里就不談了。看代碼

  1. function a(xx)
  2. {         
  3.     this.m = xx; 
  4. var b = new a(5); 

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

apply/call 調用:

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

看代碼

  1. function a(xx) {         
  2.     this.b = xx; 
  3. var o = {}; 
  4. a.apply(o, [5]); 
  5. alert(a.b);    // undefined 
  6. alert(o.b);    // 5 

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

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

所以如果一定要說有什么區(qū)別的話,看起來是這樣的

  1. function a(xx, yy) {     
  2.     alert(xx, yy);     
  3.     alert(this);     
  4.     alert(arguments); 
  5. a.apply(null, [555]); 
  6. a.call(null555); 

僅此而已。

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

  1. var m = {    
  2.     "x" : 1 
  3. }; 
  4. function foo(y) { 
  5.     alert(this.x + y); 
  6. foo.apply(m, [5]); 
  7. foo.call(m, 5); 
  8. var foo1 = foo.bind(m, 5); 
  9. foo1(); 

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

  1. 1function jam() {}; 

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

  1. var jam = function() {}; 

然后你想執(zhí)行這個函數(shù),腦洞大開的你會這么寫:

  1. function jam() {}(); 

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

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

這樣就定義了一個函數(shù)同時也執(zhí)行它,詳情參加 ECMAScript Expression Statement 章節(jié)。

本文出自 “菜鳥浮出水” 博客,原文鏈接:http://rangercyh.blog.51cto.com/1444712/1615809

責任編輯:王雪燕 來源: 51CTO博客
相關推薦

2021-06-18 07:16:17

JavaScript apply()方法call()方法

2017-10-10 14:36:07

前端Javascriptapply、call、

2024-08-26 14:35:19

JavaScript關鍵字對象

2021-12-05 08:27:56

Javascript 高階函數(shù)前端

2024-03-15 08:21:17

bindJavaScrip函數(shù)

2024-08-26 08:36:26

2024-08-20 16:04:27

JavaScript開發(fā)

2011-03-22 09:49:15

JavaScript

2021-06-09 07:01:30

前端CallApply

2021-11-30 06:56:58

CallApply函數(shù)

2015-05-15 10:04:28

localhost

2015-06-17 09:34:09

軟件定義存儲 云存儲

2015-07-01 10:25:07

Docker開源項目容器

2010-10-09 09:46:11

indexOf函數(shù)JavaScript

2014-12-12 10:46:55

Azure地緣組affinitygro

2015-06-15 13:06:23

項目項目經(jīng)驗

2015-09-29 10:26:51

pythonlogging模塊

2021-12-29 17:38:17

JavaScripttypeof前端

2010-10-08 14:31:46

Javascriptsplit函數(shù)

2015-05-20 09:44:00

Ossim流量數(shù)據(jù)
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日日夜夜天天综合 | 一级片在线观看 | 91免费电影 | 99av成人精品国语自产拍 | 狠狠操狠狠搞 | 久久在线视频 | 亚洲有码转帖 | 亚洲啊v | 不卡av电影在线播放 | 国产精品成人国产乱 | www.99热| 99爱在线视频 | 伊人精品一区二区三区 | chengrenzaixian| 欧美又大粗又爽又黄大片视频 | 2022精品国偷自产免费观看 | 在线看亚洲 | 在线小视频 | 亚洲精品视频在线播放 | 亚洲日韩中文字幕 | 成人精品一区亚洲午夜久久久 | 天堂一区 | 久久久精品网站 | 国产成人精品免高潮在线观看 | 亚洲一二三区精品 | 中文字幕精品视频 | av黄色在线 | 成人小视频在线免费观看 | 色综合天天天天做夜夜夜夜做 | 日韩欧美手机在线 | 黄色片免费看视频 | 免费国产一区二区 | 在线观看视频91 | 欧美精品久久久 | 国产精久久久久久久妇剪断 | 国产一区二区三区在线 | 欧美一级毛片免费观看 | 亚洲日日夜夜 | 午夜精品久久久 | 欧美日韩精品专区 | 成人在线视 |