2016-08-19 24 views
0

我正在閱讀關於iframe resizer的源代碼here。並得到了極其混亂的這個片段在factory()功能:在javascript中使用綁定undefined的目的是什麼?

Array.prototype.forEach.call(
        document.querySelectorAll(target || 'iframe'), 
        init.bind(undefined, options) 
       ); 

factory()功能:

function factory(){ 
    function init(options,element){ 
     function chkType(){ 
      if(!element.tagName) { 
       throw new TypeError('Object is not a valid DOM element'); 
      } else if ('IFRAME' !== element.tagName.toUpperCase()) { 
       throw new TypeError('Expected <IFRAME> tag, found <'+element.tagName+'>'); 
      } 
     } 

     if(element) { 
      debugger 
      chkType(); 
      setupIFrame(element, options); 
      iFrames.push(element); 
     } 
    } 

    var iFrames; 

    setupRequestAnimationFrame(); 
    setupEventListeners(); 

    return function iFrameResizeF(options,target){ 
     iFrames = []; //Only return iFrames past in on this call 

     switch (typeof(target)){ 
     case 'undefined': 
     case 'string': 
      Array.prototype.forEach.call(
       document.querySelectorAll(target || 'iframe'), 
       init.bind(undefined, options) 
      ); 
      break; 
     case 'object': 
      init(options,target); 
      break; 
     default: 
      throw new TypeError('Unexpected data type ('+typeof(target)+')'); 
     } 

     return iFrames; 
    }; 
} 

似乎elementinit()功能iframe元素。爲什麼init.bind(undefined, options)得到了element參數傳遞給init()函數?這個元素來自哪裏?

回答

0

.bind()創建一個新函數,其this上下文將被設置爲第一個參數,其他參數將被設置爲以下參數。爲了說明這意味着什麼:

function foo(bar, baz) {} 

var f = foo.bind({}); 
f(1, 2); 

調用f這裏,this將被設置爲{}bar1baz2

var f = foo.bind({}, 1); 
f(2); 

這實際上有相同的結果,bar1baz2

var f = foo.bind({}, 1, 2); 
f(); 

同樣的結果。

您不僅可以bind的值爲this,還可以綁定參數。

所以:

init.bind(undefined, options) 

init顯然不需要this,所以undefined被用來簡單地跳過該參數,並init第一個參數註定是options。以後要調用這個綁定函數的人可能會傳遞額外的參數。 bind這裏用來綁定第一個參數;你只需要通過什麼,爲this論點第一。

+0

但''''''init()'函數來自哪裏?它如何傳遞給該函數? – Blake

+0

綁定的'init'用作'forEach'的回調函數;所以'forEach'遍歷'document.querySelectorAll(target ||'iframe')'並且將每個'element'依次傳遞給綁定的'init'。 – deceze

+0

它基本上等同於'document.querySelectorAll(target ||'iframe').forEach(element => init(options,element))';然而,'querySelectorAll'不返回一個'Array',因此沒有'forEach',因此使用這個解決方法。 – deceze

0

看看如何使用這個工廠的API,因爲它會澄清元素來自哪裏。 基本上,調用工廠函數factory()將返回函數iFrameResizeF()。然後可以用一個或兩個參數調用該函數。

使用一個參數,您可以發送它的選項或一個CSS選擇器的字符串。 如果向它發送選項,它將綁定DOM中的所有iframe上的init()與這些選項。 如果您發送一個字符串,它將在選擇器獲取的所有元素上綁定init(),而沒有任何選項。

使用兩個參數,它只會將所有這些元素的init()與所有這些選項綁定在一起。

一旦你運行該元素的init,就會選擇正確的選項。

,這樣,代碼是這樣的:

var useFactory = factory(); 
// Two parameters 
useFactory({"option1" : "value1", "option2" : "value2"}, "selectorString"); 
// Or only parameters so all iframes are affected 
useFactory({"option1" : "value1", "option2" : "value2"}); 
// Or only a selector so the options will be set to undefined for all elements matching the selector 
useFactory("selectorString"); 

然後在其他地方的代碼,這些元素的初始化函數可能會被調用。

相關問題