精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

深入淺出妙用Javascript中apply、call、bind

開發 前端
我希望能夠通過這篇文章,能夠清晰的提升對apply、call、bind的認識,并且列出一些它們的妙用加深記憶。

[[205806]]

這篇文章實在是很難下筆,因為網上相關文章不勝枚舉。

巧合的是前些天看到阮老師的一篇文章的一句話:

“對我來說,博客首先是一種知識管理工具,其次才是傳播工具。我的技術文章,主要用來整理我還不懂的知識。我只寫那些我還沒有完全掌握的東西,那些我精通的東西,往往沒有動力寫。炫耀從來不是我的動機,好奇才是。"

對于這句話,不能贊同更多,也讓我下決心好好寫這篇,網上文章雖多,大多復制粘貼,且晦澀難懂,我希望能夠通過這篇文章,能夠清晰的提升對apply、call、bind的認識,并且列出一些它們的妙用加深記憶。

apply、call

在 javascript 中,call 和 apply 都是為了改變某個函數運行時的上下文(context)而存在的,換句話說,就是為了改變函數體內部 this 的指向。

JavaScript 的一大特點是,函數存在「定義時上下文」和「運行時上下文」以及「上下文是可以改變的」這樣的概念。

先來一個栗子:

  1. function fruits() {} 
  2.  
  3. fruits.prototype = { 
  4. color: "red"
  5. say: function() { 
  6. console.log("My color is " + this.color); 
  7.  
  8. var apple = new fruits; 
  9. apple.say(); //My color is red  

但是如果我們有一個對象banana= {color : "yellow"} ,我們不想對它重新定義 say 方法,那么我們可以通過 call 或 apply 用 apple 的 say 方法:

  1. banana = { 
  2. color: "yellow" 
  3. apple.say.call(banana); //My color is yellow 
  4. apple.say.apply(banana); //My color is yellow  

所以,可以看出 call 和 apply 是為了動態改變 this 而出現的,當一個 object 沒有某個方法(本栗子中banana沒有say方法),但是其他的有(本栗子中apple有say方法),我們可以借助call或apply用其它對象的方法來操作。

apply、call 的區別

對于 apply、call 二者而言,作用完全一樣,只是接受參數的方式不太一樣。例如,有一個函數定義如下:

  1. var func = function(arg1, arg2) { 
  2.  
  3. };  

就可以通過如下方式來調用:

  1. func.call(this, arg1, arg2); 
  2.  
  3. func.apply(this, [arg1, arg2]) 

其中 this 是你想指定的上下文,他可以是任何一個 JavaScript 對象(JavaScript 中一切皆對象),call 需要把參數按順序傳遞進去,而 apply 則是把參數放在數組里。

JavaScript 中,某個函數的參數數量是不固定的,因此要說適用條件的話,當你的參數是明確知道數量時用 call 。

而不確定的時候用 apply,然后把參數 push 進數組傳遞進去。當參數數量不確定時,函數內部也可以通過 arguments 這個數組來遍歷所有的參數。

為了鞏固加深記憶,下面列舉一些常用用法:

1、數組之間追加

  1. var array1 = [12 , "foo" , {name "Joe"} , -2458]; 
  2.  
  3. var array2 = ["Doe" , 555 , 100]; 
  4.  
  5. Array.prototype.push.apply(array1, array2); 
  6.  
  7. /* array1 值為 [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */  

2、獲取數組中的***值和最小值

  1. var numbers = [5, 458 , 120 , -215 ]; 
  2.  
  3. var maxInNumbers = Math.max.apply(Math, numbers), //458 
  4.  
  5. maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458  

number 本身沒有 max 方法,但是 Math 有,我們就可以借助 call 或者 apply 使用其方法。

3、驗證是否是數組(前提是toString()方法沒有被重寫過)

  1. functionisArray(obj){ 
  2.  
  3.     returnObject.prototype.toString.call(obj) === '[object Array]' ;  
  4.  

4、類(偽)數組使用數組方法

  1. var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*")); 

Javascript中存在一種名為偽數組的對象結構。比較特別的是 arguments 對象,還有像調用 getElementsByTagName , document.childNodes 之類的,它們返回NodeList對象都屬于偽數組。不能應用 Array下的 push , pop 等方法。

但是我們能通過 Array.prototype.slice.call 轉換為真正的數組的帶有 length 屬性的對象,這樣 domNodes 就可以應用 Array 下的所有方法了。

深入理解運用apply、call

下面就借用一道面試題,來更深入的去理解下 apply 和 call 。

定義一個 log 方法,讓它可以代理 console.log 方法,常見的解決方法是:

  1. function log(msg) { 
  2.     console.log(msg); 
  3. log(1); //1 
  4. log(1,2); //1  

上面方法可以解決最基本的需求,但是當傳入參數的個數是不確定的時候,上面的方法就失效了,這個時候就可以考慮使用 apply 或者 call,注意這里傳入多少個參數是不確定的,所以使用apply是***的,方法如下:

  1. function log(){ 
  2.     console.log.apply(console, arguments); 
  3. }; 
  4. log(1); //1 
  5. log(1,2); //1 2  

接下來的要求是給每一個 log 消息添加一個"(app)"的前輟,比如:

  1. log("hello world"); //(app)hello world 

該怎么做比較優雅呢?這個時候需要想到arguments參數是個偽數組,通過 Array.prototype.slice.call 轉化為標準數組,再使用數組方法unshift,像這樣:

  1. function log(){ 
  2.     var args = Array.prototype.slice.call(arguments); 
  3.     args.unshift('(app)'); 
  4.  
  5.     console.log.apply(console, args); 
  6. };  

bind

說完了 apply 和 call ,再來說說bind。bind() 方法與 apply 和 call 很相似,也是可以改變函數體內 this 的指向。

MDN的解釋是:bind()方法會創建一個新函數,稱為綁定函數,當調用這個綁定函數時,綁定函數會以創建它時傳入 bind()方法的***個參數作為 this,傳入 bind() 方法的第二個以及以后的參數加上綁定函數運行時本身的參數按照順序作為原函數的參數來調用原函數。

直接來看看具體如何使用,在常見的單體模式中,通常我們會使用 _this , that , self 等保存 this ,這樣我們可以在改變了上下文之后繼續引用到它。 像這樣:

  1. var foo = { 
  2. bar : 1, 
  3. eventBind: function(){ 
  4. var _this = this; 
  5. $('.someClass').on('click',function(event) { 
  6. /* Act on the event */ 
  7. console.log(_this.bar); //1 
  8. }); 
  9.  

由于 Javascript 特有的機制,上下文環境在 eventBind:function(){ } 過渡到 $('.someClass').on('click',function(event) { }) 發生了改變,上述使用變量保存 this 這些方式都是有用的,也沒有什么問題。當然使用 bind() 可以更加優雅的解決這個問題:

  1. var foo = { 
  2. bar : 1, 
  3. eventBind: function(){ 
  4. $('.someClass').on('click',function(event) { 
  5. /* Act on the event */ 
  6. console.log(this.bar); //1 
  7. }.bind(this)); 
  8.  

在上述代碼里,bind() 創建了一個函數,當這個click事件綁定在被調用的時候,它的 this 關鍵詞會被設置成被傳入的值(這里指調用bind()時傳入的參數)。因此,這里我們傳入想要的上下文 this(其實就是 foo ),到 bind() 函數中。然后,當回調函數被執行的時候, this 便指向 foo 對象。再來一個簡單的栗子:

  1. var bar = function(){ 
  2. console.log(this.x); 
  3.  
  4. bar(); // undefined 
  5. var func = bar.bind(foo); 
  6. func(); // 3  

這里我們創建了一個新的函數 func,當使用 bind() 創建一個綁定函數之后,它被執行的時候,它的 this 會被設置成 foo , 而不是像我們調用 bar() 時的全局作用域。

有個有趣的問題,如果連續 bind() 兩次,亦或者是連續 bind() 三次那么輸出的值是什么呢?像這樣:

  1. var bar = function(){ 
  2. console.log(this.x); 
  3. var foo = { 
  4. x:3 
  5. var sed = { 
  6. x:4 
  7. var func = bar.bind(foo).bind(sed); 
  8. func(); //? 
  9.  
  10. var fiv = { 
  11. x:5 
  12. var func = bar.bind(foo).bind(sed).bind(fiv); 
  13. func(); //?  

答案是,兩次都仍將輸出 3 ,而非期待中的 4 和 5 。原因是,在Javascript中,多次 bind() 是無效的。更深層次的原因, bind() 的實現,相當于使用函數在內部包了一個 call / apply ,第二次 bind() 相當于再包住***次 bind() ,故第二次以后的 bind 是無法生效的。

apply、call、bind比較

那么 apply、call、bind 三者相比較,之間又有什么異同呢?何時使用 apply、call,何時使用 bind 呢。簡單的一個栗子:

  1. var obj = { 
  2. x: 81, 
  3. }; 
  4.  
  5. var foo = { 
  6. getX: function() { 
  7. return this.x; 
  8.  
  9. console.log(foo.getX.bind(obj)()); //81 
  10. console.log(foo.getX.call(obj)); //81 
  11. console.log(foo.getX.apply(obj)); //81  

三個輸出的都是81,但是注意看使用 bind() 方法的,他后面多了對括號。

也就是說,區別是,當你希望改變上下文環境之后并非立即執行,而是回調執行的時候,使用 bind() 方法。而 apply/call 則會立即執行函數。

再總結一下:

  • apply 、 call 、bind 三者都是用來改變函數的this對象的指向的;
  • apply 、 call 、bind 三者***個參數都是this要指向的對象,也就是想指定的上下文;
  • apply 、 call 、bind 三者都可以利用后續參數傳參;
  • bind是返回對應函數,便于稍后調用;apply、call則是立即調用 。

本文實例出現的所有代碼,在我的github上可以下載。 

責任編輯:龐桂玉 來源: 前端大全
相關推薦

2022-09-26 09:01:15

語言數據JavaScript

2023-12-04 13:22:00

JavaScript異步編程

2010-07-16 09:11:40

JavaScript內存泄漏

2022-10-31 09:00:24

Promise數組參數

2012-02-21 13:55:45

JavaScript

2021-06-18 07:16:17

JavaScript apply()方法call()方法

2011-05-30 14:41:09

Javascript閉

2021-03-16 08:54:35

AQSAbstractQueJava

2011-07-04 10:39:57

Web

2022-05-26 09:20:01

JavaScript原型原型鏈

2009-06-18 10:23:03

Javascript 基本框架

2009-06-22 15:34:00

Javascript

2021-07-20 15:20:02

FlatBuffers阿里云Java

2017-07-02 18:04:53

塊加密算法AES算法

2019-01-07 15:29:07

HadoopYarn架構調度器

2012-05-21 10:06:26

FrameworkCocoa

2015-03-02 09:22:09

Javascript函數用法apply

2024-08-26 14:35:19

JavaScript關鍵字對象

2021-12-05 08:27:56

Javascript 高階函數前端

2016-12-27 09:10:29

JavaScript原型鏈繼承
點贊
收藏

51CTO技術棧公眾號

成人欧美一区二区三区黑人一 | 五月激情五月婷婷| 欧美性videos| 成人免费毛片片v| 国产成+人+综合+亚洲欧洲| 黄色裸体一级片| 国产精品毛片av| 欧美午夜在线一二页| 国产一级大片免费看| 男人久久精品| 国产成人精品免费在线| 日产精品久久久一区二区福利| 男人的午夜天堂| 亚洲品质自拍| 日韩欧美一区二区视频| 国产熟人av一二三区| 国内小视频在线看| 国产精品女上位| 黄色一区三区| 精品人妻一区二区三区三区四区| 国产视频一区三区| 萌白酱国产一区二区| mm131丰满少妇人体欣赏图| 日韩一级淫片| 欧美亚洲国产一区二区三区va| 狠狠干视频网站| 在线激情免费视频| 久久久久久9999| 久久精品magnetxturnbtih| av资源免费看| 久久国产人妖系列| 国产精品看片资源| 亚洲自拍一区在线观看| 亚洲激情婷婷| 欧美日产国产成人免费图片| 女人18毛片毛片毛片毛片区二| 亚洲人成网亚洲欧洲无码| 精品少妇一区二区| 黑人性生活视频| 成人乱码手机视频| 51精品视频一区二区三区| 天美星空大象mv在线观看视频| 樱花草涩涩www在线播放| 亚洲国产视频直播| www.国产在线播放| 超碰在线中文字幕| 午夜视频在线观看一区二区 | 欧美日韩精品系列| 邪恶网站在线观看| 精品176极品一区| 欧美日韩在线播放| 色噜噜狠狠永久免费| 日本h片久久| 欧美日韩国产免费一区二区 | 日韩av懂色| 欧美日韩免费视频| 亚洲美女性囗交| 国产欧美视频在线| 日韩色视频在线观看| 五月天六月丁香| 欧美h版在线观看| 欧美一区二区三区不卡| 色哟哟网站在线观看| 一区二区三区在线免费看| 精品国内二区三区| 波多野结衣有码| 免费欧美一区| 中文字幕久热精品在线视频| 秋霞网一区二区三区| 久久综合电影| 色综合老司机第九色激情| 国产精彩视频在线| 美女视频一区免费观看| 国产精品久久久久国产a级| 中文字幕人成人乱码亚洲电影| 久久国产精品99久久久久久老狼 | av中文字幕免费| 成人18视频在线播放| 欧美精品亚洲精品| 欧美13一16娇小xxxx| 亚洲激情网站免费观看| 国产精品自拍片| 国产69精品久久久久9999人| 7777精品伊人久久久大香线蕉经典版下载 | 中文字幕日韩精品无码内射| 岛国毛片av在线| 在线视频一区二区三| 欧美性受xxxxxx黑人xyx性爽| 欧洲精品99毛片免费高清观看| 精品免费99久久| 永久免费av无码网站性色av| 中出一区二区| 欧美孕妇毛茸茸xxxx| 亚洲天堂avav| 不卡av在线网| 一本一道久久久a久久久精品91 | 日韩av片电影专区| 国产男男gay网站| 91片黄在线观看| 成年人免费观看的视频| 九色porny视频在线观看| 在线日韩一区二区| 国模无码视频一区| 色一区二区三区四区| 久久人人爽人人爽人人片av高清| 色老头在线视频| 成人av网站在线观看| 亚洲精品国产系列| 性欧美xxx69hd高清| 91精品国产福利| 最近中文字幕在线mv视频在线| 欧美激情日韩| 国产精品一区二区3区| 婷婷五月综合激情| 一区二区三区四区不卡视频| 在线观看的毛片| 女同一区二区三区| 欧美激情xxxxx| 中文字幕一区二区三区四区免费看| 白白色 亚洲乱淫| 免费成人深夜夜行网站视频| 国产91在线精品| 亚洲欧美中文日韩在线| 国产五月天婷婷| 国产高清精品久久久久| 一区二区三区国| 国产私拍福利精品视频二区| 精品视频偷偷看在线观看| 久久一二三四区| 国产精品99久久久久久有的能看| 在线观看福利一区| 欧美色片在线观看| 国产亚洲欧洲在线| 丰满少妇xoxoxo视频| 久久中文娱乐网| 国产精品后入内射日本在线观看| 午夜视频在线观看精品中文| 久久久av电影| 国产乱淫a∨片免费观看| 欧美激情资源网| 亚洲成人av免费看| 精品国内自产拍在线观看视频| 青青草成人在线| 日夜干在线视频| 日韩欧美主播在线| 巨胸大乳www视频免费观看| 亚洲每日更新| 久久久久久高清| 欧美momandson| 亚洲三级av在线| 波多野结衣视频观看| 久久蜜桃香蕉精品一区二区三区| avav在线看| 欧美伦理影院| 成人福利视频网| 蜜桃视频在线观看免费视频网站www| 欧美日韩国产高清一区二区 | 亚洲一区二区三区在线看| 亚洲av无码久久精品色欲| 国色天香一区二区| 久久久久久久久久久一区| 成人欧美一区二区三区的电影| 亚洲欧美日韩中文在线| 亚洲精品一区二三区| 国产精品久久久久四虎| 午夜av中文字幕| 黑人一区二区三区四区五区| 国产亚洲情侣一区二区无| 亚洲美女久久精品| 一本色道久久88综合亚洲精品ⅰ | 亚洲免费久久| 欧美国产亚洲精品| 97视频com| 成年人在线观看视频| 欧美日韩成人综合在线一区二区| 欧美精品久久久久久久久46p| 国产91在线|亚洲| 免费日韩视频在线观看| 999国产精品永久免费视频app| 亚洲va码欧洲m码| 少妇视频一区| 日韩网站免费观看高清| 懂色av蜜臀av粉嫩av分享吧| 日韩欧美国产网站| 亚洲综合久久av一区二区三区| 成人av在线一区二区三区| 男女视频在线看| 欧美日一区二区在线观看 | 免费一级在线观看| 欧美老人xxxx18| 亚洲精品视频在线观看免费视频| 欧美经典三级视频一区二区三区| 一级片免费在线观看视频| 中文一区二区| 水蜜桃在线免费观看| 亚洲精品国产精品粉嫩| 亚洲一区二区三区四区在线播放| 亚洲精品永久免费视频| 麻豆国产精品va在线观看不卡 | 94色蜜桃网一区二区三区| av污在线观看| 国产精品久久久久久模特| 在线看视频不卡| 亚洲小说图片视频| dy888夜精品国产专区| 免费高清视频在线一区| 性欧美激情精品| 老司机精品视频在线观看6| 亚洲精品网址在线观看| 国产极品久久久| 欧美视频一二三区| 久久久久久91亚洲精品中文字幕| 亚洲男人的天堂av| 青青草华人在线视频| 91麻豆免费看片| 日本黄色大片在线观看| 精品一区二区免费在线观看| 成年人黄色片视频| 国内精品美女在线观看| 在线观看欧美激情| 欧美亚洲国产激情| 你懂的视频在线一区二区| 国产精品超碰| 999在线观看免费大全电视剧| 99久久婷婷国产综合精品首页 | 天天干天天干天天| 亚洲国产日韩精品| 日韩在线中文字幕视频| 国产精品毛片a∨一区二区三区| 泷泽萝拉在线播放| 99久久国产综合精品麻豆| 又大又长粗又爽又黄少妇视频| 国产综合久久久久久鬼色| 天天干在线影院| 日韩成人午夜精品| 国产精品涩涩涩视频网站| 国产精品综合色区在线观看| 阿v天堂2017| 性xx色xx综合久久久xx| 男人日女人逼逼| 亚洲伊人网站| aaa毛片在线观看| 久久精品毛片| 黄色国产小视频| 免费看黄色91| 亚洲 国产 图片| 国模无码大尺度一区二区三区| 国产永久免费网站| 国产一区视频在线看| 男生和女生一起差差差视频| 国产一区二区三区久久久| 国产吃瓜黑料一区二区| 成人一二三区视频| 国产精品成人99一区无码| 99久久亚洲一区二区三区青草| 日本69式三人交| www日韩大片| 日韩丰满少妇无码内射| 国产精品免费看片| 神马午夜精品91| 一区二区三区欧美视频| 日韩激情一区二区三区| 舔着乳尖日韩一区| aaaaaa毛片| 欧美日韩一区二区在线观看| 国产精品无码专区av免费播放| 欧美一区二区三区白人 | 国产一区二区三区视频免费| 色多多视频在线观看| 欧美老女人性视频| 欧美xxxhd| 国产精品视频内| 日韩影片在线观看| 久久久久久久久久码影片| 欧美在线观看视频一区| 麻豆传媒网站在线观看| 日韩亚洲精品在线| gogogo高清免费观看在线视频| 国产一区二区不卡在线| 最近日本中文字幕| 国产精品美女一区二区| 久久久久噜噜噜亚洲熟女综合| 日韩欧美国产视频| 精品久久无码中文字幕| 亚洲欧洲xxxx| 在线观看h网| 热久久免费视频精品| 精品999日本久久久影院| 久久久久久欧美精品色一二三四| 97精品视频| 又粗又黑又大的吊av| 麻豆成人91精品二区三区| 人妖粗暴刺激videos呻吟| 中文字幕精品一区二区三区精品| 精品无码久久久久久久| 欧美午夜电影网| 人妻少妇精品无码专区| 久久久国产精品亚洲一区| 天堂√8在线中文| 97免费资源站| 欧美一区三区| 免费国产a级片| 久久国产免费看| 日本一区二区在线观看视频| 国产精品久久久久一区二区三区| 青青草成人av| 日韩午夜三级在线| 欧美人xxx| 国产精品99久久99久久久二8| 成人中文字幕视频| 成人性做爰片免费视频| 日韩高清不卡一区二区| 波多野结衣影院| 亚洲精品视频在线看| 中文字幕一区二区在线视频 | 1pondo在线播放免费| 性亚洲最疯狂xxxx高清| 精品国产乱码一区二区三区| 神马影院我不卡| 香蕉久久夜色精品国产| 亚洲精品第二页| 一区二区三区日韩欧美精品| 在线观看国产精品视频| 国产亚洲xxx| 裤袜国产欧美精品一区| 久久国产精品 国产精品| 激情综合视频| 国产精久久久久| 一区二区三区小说| 国产喷水吹潮视频www| 最近2019中文字幕第三页视频| 色老太综合网| 欧美主播一区二区三区美女 久久精品人| 一区二区三区国产在线| 中文字幕第九页| 亚洲国产成人tv| 蜜臀av免费在线观看| 精品中文字幕在线| 日韩在线成人| 黄色三级中文字幕| 国产aⅴ精品一区二区三区色成熟| 午夜免费激情视频| 欧美一区二区人人喊爽| 性爱视频在线播放| yellow视频在线观看一区二区| 午夜日韩福利| 亚洲精品第二页| 欧美日韩一区二区精品| 牛牛影视精品影视| 国产精品电影网| 日本久久精品| 国产成人美女视频| 亚洲精品午夜久久久| 免费观看国产视频| 91超碰中文字幕久久精品| 要久久电视剧全集免费| 欧美精品第三页| 国产精品久久久久影院老司| 国产强被迫伦姧在线观看无码| 欧美疯狂做受xxxx高潮| 欧美三级午夜理伦三级小说| 黄色片一级视频| 国产精品美女久久久久久久网站| 国产一区二区视频免费观看| 久久成人在线视频| 另类在线视频| 手机看片福利日韩| 亚洲人吸女人奶水| 日本高清视频免费观看| 日本欧美精品在线| 亚洲大全视频| 免费的av网站| 欧美日韩中文国产| 日本孕妇大胆孕交无码| 久久99精品久久久久久青青日本 | 亚洲一区二区三区香蕉| 亚洲国内欧美| av手机在线播放| 日韩一区二区电影在线| 99在线视频影院| 日韩精品不卡| 高清在线观看日韩| 黄色av网站免费| 欧美国产日韩中文字幕在线| 偷拍精品福利视频导航| 日韩av一卡二卡三卡| 午夜日韩在线电影| 日本精品一区二区三区在线播放| eeuss一区二区三区| 日韩精品91亚洲二区在线观看| 日韩视频中文字幕在线观看| 国产视频亚洲视频| 亚洲不卡视频| 男女无套免费视频网站动漫| 一区二区理论电影在线观看| 成人在线免费观看| 国产精品一区二| 国内一区二区视频| 中文字幕av影院| 久久久人成影片一区二区三区|