99热99这里只有精品6国产,亚洲中文字幕在线天天更新,在线观看亚洲精品国产福利片 ,久久久久综合网

歡迎加入QQ討論群258996829
麥子學院 頭像
蘋果6袋
6
麥子學院

Javascript函數(shù)學習之調(diào)用模式詳解

發(fā)布時間:2017-07-06 10:17  回復:0  查看:2032   最后回復:2017-07-06 10:17  
函數(shù)是JavaScript 世界里的第一公民,換句話來說,就是我們?nèi)绻梢跃?/span> JavaScript 函數(shù)的使用,那么對 JavaScript 的運用可以更游刃有余了。熟悉 JavaScript 的人應(yīng)該都知道,同樣的函數(shù),以不同的方式調(diào)用的話,受影響最大的應(yīng)該是  this  。下面我們來說說 JavaScript 函數(shù)的各種調(diào)用模式,希望對大家 學習javascript有所幫助。
   一、普通函數(shù)的調(diào)用模式
  所謂普通函數(shù)的調(diào)用模式,也是JavaScript 函數(shù)的最簡單的一種調(diào)用模式,直接就是函數(shù)名后接一個  ()   實現(xiàn)調(diào)用,看下面代碼:
   function  func(){
  console.log( this === window);  //true
  }
  func();
  上面代碼,我們用function 關(guān)鍵字聲明了一個  func  函數(shù),并且在函數(shù)體內(nèi)打印  this===window ,然后我們直接調(diào)用函數(shù) func ,我們可以看到控制臺是直接打印出  true  ,也就是說, 函數(shù)的這種普通調(diào)用模式,函數(shù)體內(nèi)的  this   是指向全局環(huán)境  window  的 。不清楚這點的同學,可以能會遇到這樣的一個 bug
   var color = 'gg'; var obj = {
  color : 'red',
  show :  function(){
   function  func1(){
  console.log( this.color);  //gg
  }
  func1();
  }
  }
  obj.show();
  我們在全局環(huán)境下聲明了一個變量 color  和一個對象  obj  ,在對象  obj  里面我們還聲明了一個  color  屬性 為  'red' ,一個  show  方法。而且在  show  方法里面呢,我們還聲明了一個函數(shù)  func1  并且調(diào)用了  func1 func1  的作用是打印  this.color 。最后我們運行代碼 obj.show();    調(diào)用 obj 里面的 show 方法。不清楚函數(shù)的普通調(diào)用模式的特點的同學可能會認為此時在控制臺答應(yīng)出來的會是  'red'  。實際上此時在控制臺答應(yīng)出來的應(yīng)該是  gg   。因為函數(shù)  func1   的調(diào)用模式是 普通函數(shù)調(diào)用模式(即使它是在  obj   的  show   方法里面調(diào)用的),所以此時函數(shù)體內(nèi)的  this   是指向 全局環(huán)境 window  的,所以就打印了全局環(huán)境下的變量  color 
  可能有些同學會問:如果我們希望  func1   函數(shù)打印出來的是  'red'  呢,應(yīng)該怎么改?其實很簡單,因為  obj.color   才是  'red'  ,所以我們只需要把  指向  obj   的  this  引入到函數(shù)  func1   里面就行了:
   var color = 'gg'; var obj = {
  color : 'red',
  show :  function(){
   var that =  this;
   function  func1(){
  console.log(that.color);  //red
  }
  func1();
  }
  }
  obj.show();
  在上面的代碼中,因為  show   里面的    this   指向    obj    的,所以我們在  show   里面聲明一個變量  that = this; 用來把指向  obj   this   引入到  func1  中,然后再把  func1  函數(shù)體內(nèi)的  this.color   改為  that.color , 此時在控制臺打印出來的就是我們想要的  'red'  了。
  可能現(xiàn)在又有同學會問:為什么   show    里面的  this   是指向  obj  的呢?這就是我們要說的 JavaScript 函數(shù)的第二種調(diào)用模式:方法調(diào)用模式
   二、方法調(diào)用模式
  方法調(diào)用模式,簡單來說就是把一個 JavaScript 函數(shù)作為一個對象的方法來調(diào)用,當一個函數(shù)被保存為一個對象的屬性是,我們就把它稱為方法,例如上文的  obj   對象里的  show   , 當一個方法被調(diào)用時,函數(shù)體里面的    this   就會綁定到這個對象 ,例如上文的 show  里面的  this   。方法調(diào)用模式也很容易辨別: obj.show() ,對象名  屬性名  ()  ;代碼的話可以參考上文的  obj   代碼 ,博主就不多寫了。記?。?方法的調(diào)用是可以在函數(shù)體內(nèi)通過  this   訪問自己所屬的那個對象的。
   三、構(gòu)造器調(diào)用模式
  博主認為構(gòu)造器調(diào)用模式是相對于其他模式來說較為復雜點的調(diào)用模式了。通過關(guān)鍵字  new   可以把一個函數(shù)作為構(gòu)造器來調(diào)用。關(guān)鍵字  new   可以改變函數(shù)的返回值:
   function  func2( name){
  this.name = name;
  }
   name;   //undefined
  // 普通函數(shù)調(diào)用模式 var foo = func2('afei');
  foo;  //undefined name;   //afei
  // 構(gòu)造器調(diào)用模式 var bar = new func2('lizefei');
  bar.__proto__ === func2.prototype;  //true
  bar;  //{name:'lizefei'}
  bar. name;  //'lizefei'
  在上示代碼中我們聲明了一個函數(shù) func2  ,分別用兩種不同的調(diào)用模式去調(diào)用它。因為函數(shù)  func2   并沒有顯式返回值,所以作為普通函數(shù)去調(diào)用時,它什么也沒有返回,所以  foo   的值是  undefined   。因為普通調(diào)用模式的    this    是指向 全局環(huán)境    window   的,所以  func2('afei');   后,全局環(huán)境下就多了一個  name  變量且等于  'afei' 。
  func2   作為構(gòu)造器調(diào)用時,我們可以看到,它返回的是一個對象,因為關(guān)鍵字  new   使得函數(shù)在調(diào)用是發(fā)生了如下的特殊變化:
  1.  創(chuàng)建了一個新對象,而且這個新對象是鏈接到  func2   的  prototype   屬性的
  2.  把函數(shù)里的  this   指向了這個新對象
  3.  如果沒有顯式的返回值,新對象作為構(gòu)造器 func2 的返回值進行返回(所以 bar  是  {name:'lizefei'}
  這樣子我們就可以看出構(gòu)造器的作用:通過函數(shù)的調(diào)用來初始化新創(chuàng)建出來的對象。在JavaScript 的面向?qū)ο缶幊汤锩?,這個可是相當重要的。
  因為在函數(shù)的聲明上,在未來作為構(gòu)造器調(diào)用的函數(shù)和普通函數(shù)的聲明沒什么區(qū)別,所以導致后來的開發(fā)者很容易因為調(diào)用模式的錯誤導致程序出問題。所以開發(fā)者們都默契地約定,  用來做構(gòu)造器調(diào)用的函數(shù)的函數(shù)名的第一個字符應(yīng)該大寫  ,例如:Person , People 。這樣子后來的開發(fā)者一看到函數(shù)名就知道要用構(gòu)造器調(diào)用模式調(diào)用此函數(shù)了。
   四、使用apply()call()方法調(diào)用
  這種調(diào)用的模式是為了更靈活控制函數(shù)運行的上下文環(huán)境而誕生的。簡單的說就是為了靈活控制函數(shù)體內(nèi)  this   的值。
  apply  和  call 這兩個方法的第一個參數(shù)都是要傳遞被函數(shù)上下文的對象(簡單點說就是要綁定給函數(shù)  this   的對象)。其他參數(shù)就有所不同了:
  apply 方法的第二個參數(shù)是一個數(shù)組,數(shù)組里面的值將作為函數(shù)調(diào)用的參數(shù);
  call 方法,從第二個參數(shù)起(包括第二個參數(shù)),剩下的參數(shù)都是作為函數(shù)調(diào)用的參數(shù);
  讓我們看看栗子:
   var obj = {
  name :'afei'
  } function  say(ag1,ag2){
  console.log(ag1+':'+ag2+" "+  this.name);
  }
  say.apply(obj,['apply 方法 ','hello']); //apply 方法 :hello afei
  say.call(obj,'call 方法 ','hi'); //call 方法 :hi afei
  正如栗子所示,我們把對象 obj   作為函數(shù)  say   的上下文來調(diào)用函數(shù)  say   ,所以函數(shù)里的  this   是指向 對象  obj   的。在 apply 方法里,我們通過數(shù)組  ['apply 方法 ','hello']   給  say   方法傳遞了兩個參數(shù)( 'apply 方法 和  'hello' ),所以打印出來是:  apply 方法 :hello afei
  同理  call  也是一樣,而且函數(shù)傳遞的方式通過上面的代碼也一目了然我,博主就不多做解釋了。
  另外,博主還聽說apply call 這兩個方法除了傳遞參數(shù)的方式不一樣,執(zhí)行的速度還是 apply  比  call  要快呢。不過博主就沒有實驗過。
   五、總結(jié)
  在JavaScript 里面,函數(shù)只要的調(diào)用模式就是這幾種了(在 ES6 里面還有一種很奇怪很特殊的函數(shù)調(diào)用模式,叫做 標簽?zāi)0?/span> ,在這里博主也不多說了,有空另更),只要掌握了這幾種主要的調(diào)用模式,那么日后再也不用擔心  this  的值變來變?nèi)チ恕?/span>
來源: 博客園
您還未登錄,請先登錄

熱門帖子

最新帖子

?