精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

欧美大胆视频| 黄色成人一级片| 亚洲另类av| 色综合天天狠狠| 日本一区二区精品视频| 波多野结衣影片| 成人网18免费网站| 欧美日韩亚洲天堂| 欧美12av| 午夜一区二区三区四区| 欧美美女黄色| 日本韩国精品在线| 亚洲国产欧美一区二区三区不卡| 麻豆av一区二区| 日韩av卡一卡二| 在线视频观看国产| 成人h版在线观看| 久久久久国产精品免费网站| 国产精品一级黄片| 国语自产精品视频在线看抢先版结局| 亚洲欧美电影院| www.久久久| 久久亚洲精品国产| 成人在线丰满少妇av| 欧美日韩中字一区| 国产一级不卡视频| 你懂的在线网址| 久久99国产精品尤物| 欧美高清视频在线观看| 亚洲天堂成人av| 日本午夜精品久久久久| 亚洲精品国产精华液| 久久99国产精品99久久| 在线天堂中文字幕| 911精品美国片911久久久| 欧美裸体bbwbbwbbw| www.好吊操| 成人精品一区二区| 国产凹凸在线观看一区二区| 欧美精品久久久久久久免费观看 | 欧美第一在线视频| 精品国产福利视频| 久久久久久艹| 国产成a人亚洲精v品无码| 免费国产自线拍一欧美视频| 欧美大片va欧美在线播放| 99久久人妻无码精品系列| 欧美黑粗硬大| 欧美日韩中文字幕综合视频| 亚洲欧洲日本国产| 天天干在线观看| 国产专区欧美精品| 国产美女精彩久久| 国产精品视频一区在线观看| 欧美日韩少妇| 久久综合免费视频| 久草福利资源在线| 欧美日韩中字| 国产一区二区动漫| 国产伦精品一区二区三区妓女| 久久爱www.| 在线视频综合导航| 91蝌蚪视频在线观看| brazzers在线观看| 一区二区在线免费| 亚洲成人第一| 77导航福利在线| 国产亚洲一区二区三区在线观看| 久久久久一区二区| 亚洲国产精品视频在线| 成人在线综合网站| 亚洲xxxx在线| av免费在线不卡| 国产精品1区2区| 亚洲自拍偷拍视频| 国产福利第一视频| 国产精品77777| 国产精品xxx在线观看www| 国产ts变态重口人妖hd| 国产丶欧美丶日本不卡视频| 亚洲影院色无极综合| 性一交一乱一乱一视频| 成人h动漫精品| 久久99精品久久久久久久久久| 亚洲经典一区二区三区| 成人精品视频.| 免费日韩av电影| 日色在线视频| 久久久国产综合精品女国产盗摄| 日本一区二区三区视频在线观看 | 免费观看av网站| 国产精品嫩草影院在线看| 精品无码久久久久久国产| 91精品人妻一区二区| 日韩激情啪啪| 色综合伊人色综合网| 久久爱一区二区| 亚洲一本二本| 欧美精品一区三区| 91video| 日韩高清一级片| 成人国产精品久久久| 亚洲精品无amm毛片| 久久先锋影音av| 日本视频精品一区| 欧美成年黄网站色视频| 午夜视黄欧洲亚洲| 日韩av片在线看| 成人自拍视频网| 欧美巨大另类极品videosbest| 深田咏美中文字幕| 国产欧美日韩在线一区二区| 尤物九九久久国产精品的分类| 91麻豆精品成人一区二区| 亚洲精品1区2区| 国产精品黄色av| 国产ts变态重口人妖hd| 久久久久久久性| 亚洲欧美综合一区| 波多野结衣在线播放| 色狠狠桃花综合| 国产又粗又猛又爽又黄| 欧美日韩黄网站| 中文日韩电影网站| 国产乡下妇女做爰毛片| 日本va欧美va欧美va精品| 国产精品一区二区三区观看| 国产福利在线| 亚洲高清在线视频| 亚洲色图 在线视频| 欧美三级午夜理伦三级小说| 色系列之999| 欧美精品二区三区| 免费在线看一区| 欧洲精品亚洲精品| 182在线播放| 欧美日韩国产色站一区二区三区| 欧美一级大片免费看| 成人久久综合| 欧美最猛性xxxxx免费| 国产成人麻豆精品午夜在线| 日本一区二区动态图| 日韩欧美一区二| 国产精品一区免费在线| 亚洲天堂视频在线观看| 久久不卡免费视频| 国产精品综合av一区二区国产馆| 日韩福利二区| 色在线视频观看| 欧美吻胸吃奶大尺度电影| 亚洲午夜久久久久久久久红桃| 欧美成人一品| 国产一区欧美二区三区| 深夜影院在线观看| 欧美日韩国产黄| 91人人澡人人爽| 91成人观看| 国产精品高潮呻吟久久av无限 | 91久久久久久久久| 番号集在线观看| 欧美性xxxxhd| 1314成人网| 一本到12不卡视频在线dvd| 国产精品尤物福利片在线观看| 你懂的在线视频| 在线观看日韩高清av| 成年人免费观看视频网站| 99在线精品免费视频九九视| 高清国产在线一区| 白白色在线观看| 亚洲国产精品人久久电影| 日本特黄特色aaa大片免费| 国产91高潮流白浆在线麻豆| 一本一本久久a久久精品综合妖精| 992tv国产精品成人影院| 国产亚洲精品激情久久| 中文字幕一区二区三区人妻四季| 91看片淫黄大片一级| 国产情侣av自拍| 日韩欧美视频在线播放| 国产一区二区在线免费视频| 中文字幕在线免费| 欧美一区二区三区免费在线看| 性生交大片免费全黄| 极品美女销魂一区二区三区 | 欧美另类交人妖| 国产精品爽爽久久久久久| 久久久高清一区二区三区| wwwwxxxx日韩| 午夜精品一区二区三区国产| 亚洲最大av在线| 免费污视频在线观看| 精品无人国产偷自产在线| 国产成人a v| 亚洲视频在线观看一区| 国产精品一区二区在线免费观看| 136国产福利精品导航网址| 久久99精品久久久久久秒播放器| 亚洲承认视频| 永久免费看mv网站入口亚洲| 国产精品人人妻人人爽| 亚洲自拍偷拍综合| 亚洲少妇18p| 久久国产精品99久久久久久老狼 | 一二三区视频在线观看| 99香蕉国产精品偷在线观看| 欧洲一区二区在线| 日韩视频1区| 欧美在线国产精品| 日本福利在线| 91麻豆精品国产| 91国产丝袜播放在线| 中文字幕精品—区二区四季| 在线观看日本www| 欧美一级播放| 一道本在线观看视频| 欧美激情极品| 国产欧美一区二区白浆黑人| 超碰在线cao| 色偷偷噜噜噜亚洲男人| 人妻中文字幕一区| 精品视频一区三区九区| 日韩欧美亚洲视频| 亚洲欧美aⅴ...| 久久久久久国产精品无码| 国产在线精品免费av| 日韩视频免费在线播放| 欧美日本不卡高清| 亚洲国产一区二区三区在线| 亚洲高清在线一区| 国产精品香蕉国产| 韩国精品一区| 欧美另类老女人| 毛片免费不卡| 在线播放日韩欧美| 六月婷婷综合网| 91精品国产综合久久久久久久久久| 国产精品第5页| 亚洲第一激情av| 91 在线视频| 欧美国产禁国产网站cc| 女性生殖扒开酷刑vk| 国产一区二区在线看| caoporn超碰97| 欧美日韩国产成人精品| 亚洲巨乳在线观看| 国产精品jk白丝蜜臀av小说| 成人黄色片网站| 成人日韩av| 国产精品久久激情| 日韩精品99| 91精品国产高清| 久久免费电影| 久久久久久国产精品久久| 污视频免费在线观看| 久热精品视频在线观看一区| 福利在线播放| 在线看日韩欧美| 国产小视频免费在线网址| 亚洲国产91色在线| 欧美一级淫片免费视频魅影视频| 欧美日韩国产高清一区二区三区 | 欧美孕妇性xxxⅹ精品hd| 亚洲精品ady| 无码国产色欲xxxx视频| 亚洲国产精品yw在线观看| 欧美视频在线观看一区二区三区| 精品久久久久av影院| 成人福利小视频| 欧美电视剧在线看免费| 精品国产av 无码一区二区三区| 欧美伊人久久大香线蕉综合69| 欧美视频xxxx| 欧美三级在线看| 夜夜爽8888| 日韩毛片免费视频一级特黄| 久久久久久一区二区三区| 国产传媒在线观看| 欧美专区第一页| 欧洲美女精品免费观看视频| 91老司机在线| 中文无码日韩欧| 久久综合婷婷综合| 成人羞羞动漫| 青青草视频国产| 一区二区91| 亚洲狼人综合干| 国产河南妇女毛片精品久久久| 少妇激情一区二区三区视频| 久久久精品黄色| 婷婷激情四射网| 午夜电影一区二区| 中国女人一级一次看片| 精品国产免费一区二区三区香蕉| 免费人成在线观看网站| 久久精品2019中文字幕| 91白丝在线| 国产欧美一区二区三区久久人妖| 91精品啪在线观看国产爱臀| 欧美国产一区二区在线| 女人色偷偷aa久久天堂| 国产精品宾馆在线精品酒店| 精品伊人久久久久7777人| 国产 xxxx| 综合分类小说区另类春色亚洲小说欧美| 亚洲国产综合久久| 欧美日韩国产大片| 天天干,夜夜操| 久久久av一区| 国产超碰精品| 成人一区二区三区四区| 青青一区二区三区| 五月丁香综合缴情六月小说| 麻豆成人综合网| 少妇特黄一区二区三区| 亚洲精品成a人| 中文字幕在线2018| 精品视频在线观看日韩| 男女在线观看视频| 国产日韩欧美黄色| 狠狠做六月爱婷婷综合aⅴ| 被灌满精子的波多野结衣| 久久精品国产色蜜蜜麻豆| free性中国hd国语露脸| 亚洲国产综合91精品麻豆| 国产麻豆免费观看| 一区二区三区国产视频| 日韩激情电影免费看| av日韩中文字幕| 亚洲a在线视频| 超碰在线97免费| 国产日韩一级二级三级| www..com国产| 亚洲成人精品视频| 日本天码aⅴ片在线电影网站| 成人黄色影片在线| 成人三级视频| 91国产精品视频在线观看| 国产亚洲欧美一级| 中文字幕国产在线观看| 日韩av在线免费看| 国产色播av在线| 成人动漫视频在线观看免费| 中文在线播放一区二区| 91网址在线观看精品| 亚洲女爱视频在线| 国产乱码精品一区二三区蜜臂| 综合136福利视频在线| 深夜视频一区二区| 日韩欧美在线电影| 日本中文字幕一区二区视频| 人人妻人人藻人人爽欧美一区| 欧美日韩美女在线| 九九九伊在人线综合| 国产福利精品在线| 欧美中文一区二区| 国产精品视频中文字幕| 国产精品免费丝袜| 国产一区二区三区在线观看| 色偷偷888欧美精品久久久| 亚洲tv在线| 99久re热视频精品98| 国产精品99久久久久久久女警| 青青草成人免费| 精品国产一区二区亚洲人成毛片 | 欧美专区福利在线| 欧美做受69| 激情网站五月天| 中文字幕乱码亚洲精品一区| 少妇又紧又色又爽又刺激视频| 神马久久久久久| 视频亚洲一区二区| 波多野结衣综合网| 久久久久久久综合| 一区二区精品视频在线观看| 久久在线视频在线| 国产福利一区二区精品秒拍| 男人操女人免费软件| 中文一区二区完整视频在线观看 | 6699嫩草久久久精品影院| 国产一区二区中文字幕免费看| 国产日韩亚洲| 少妇太紧太爽又黄又硬又爽小说 | 97超碰国产精品女人人人爽| 亚洲国产欧美日韩在线观看第一区| 91蝌蚪视频在线观看| 亚洲欧美aⅴ...| 午夜在线视频免费| 国产精品人成电影在线观看| 你懂的视频一区二区| 51调教丨国产调教视频| 欧美丝袜丝交足nylons| 污片在线免费观看| 欧美日韩一区综合| 韩国成人精品a∨在线观看| 国产福利拍拍拍| 中文字幕自拍vr一区二区三区| 国产成人一二片| 天天爽人人爽夜夜爽| 亚洲国产裸拍裸体视频在线观看乱了 |