ฉันต้องการเข้าใจไวยากรณ์ของปลั๊กอิน jQuery


89

ไซต์ jQuery แสดงรายการไวยากรณ์ปลั๊กอินพื้นฐานสำหรับ jQuery ดังนี้:

(function( $ ){    
  $.fn.myPlugin = function() {      
    // there's no need to do $(this) because
    // "this" is already a jquery object

    // $(this) would be the same as $($('#element'));

    this.fadeIn('normal', function(){    
      // the this keyword is a DOM element    
    });    
  };
})( jQuery );

ฉันแค่อยากจะเข้าใจว่าเกิดอะไรขึ้นที่นั่นจากมุมมองของ Javascript เพราะดูเหมือนว่ามันจะไม่เป็นไปตามไวยากรณ์ใด ๆ ที่ฉันเคยเห็น JS ทำมาก่อน นี่คือรายการคำถามของฉัน:

  1. หากคุณแทนที่ฟังก์ชัน ($) ... ด้วยตัวแปรให้พูดว่า "the_function" ไวยากรณ์จะมีลักษณะดังนี้:

     (the_function)( jQuery );
    

    "(jQuery);" คืออะไร ทำ? วงเล็บรอบฟังก์ชันจำเป็นจริงหรือ? ทำไมพวกเขาถึงอยู่ที่นั่น? มีรหัสชิ้นอื่นที่คุณสามารถให้ที่คล้ายกันได้หรือไม่?

  2. เริ่มต้นด้วยฟังก์ชัน ($) มันเป็นการสร้างฟังก์ชั่นเท่าที่ฉันบอกได้ว่าจะไม่ถูกรันด้วยพารามิเตอร์ $ ซึ่งถูกกำหนดไว้แล้ว? เกิดอะไรขึ้นที่นั่น?

ขอบคุณสำหรับความช่วยเหลือ!

คำตอบ:


130
function(x){ 
    x...
}

เป็นเพียงฟังก์ชันที่ไม่มีชื่อซึ่งใช้อาร์กิวเมนต์เดียวคือ "x" และทำสิ่งต่างๆด้วย x

แทนที่จะใช้ 'x' ซึ่งเป็นชื่อตัวแปรทั่วไปคุณสามารถใช้ $ ซึ่งเป็นชื่อตัวแปรที่ใช้กันน้อยกว่า แต่ยังคงถูกต้องตามกฎหมาย

function($){ 
    $...
}

ฉันจะใส่ไว้ในวงเล็บเพื่อให้แน่ใจว่ามันแยกวิเคราะห์เป็นนิพจน์:

(function($){
    $....
})

ในการเรียกใช้ฟังก์ชันคุณใส่ () ต่อท้ายด้วยรายการอาร์กิวเมนต์ ตัวอย่างเช่นหากเราต้องการเรียกใช้ฟังก์ชันนี้ผ่าน 3 เพื่อหาค่า$เราจะทำสิ่งนี้:

(function($){
    $...
})(3);

สำหรับการเตะขอเรียกฟังก์ชันนี้และส่ง jQuery เป็นตัวแปร:

(function($){
     $....
})(jQuery);

สิ่งนี้จะสร้างฟังก์ชันใหม่ที่รับหนึ่งอาร์กิวเมนต์แล้วเรียกใช้ฟังก์ชันนั้นโดยส่งผ่าน jQuery เป็นค่า

ทำไม?

  • เพราะการเขียน jQuery ทุกครั้งที่คุณต้องการทำอะไรกับ jQuery เป็นเรื่องที่น่าเบื่อ

ทำไมไม่เพียงแค่เขียน$ = jQuery?

  • เพราะอาจมีคนอื่นกำหนดให้ $ หมายถึงอย่างอื่น สิ่งนี้รับประกันได้ว่าความหมายอื่นใดของ $ ถูกบังไว้

20
เป็นที่ชัดเจน แต่มันหายไปรายละเอียดเพิ่มเติมเกี่ยวกับความจำเป็นที่จะแนะนำตัวแยกวิเคราะห์ลงในการแยกความหมายฟังก์ชั่นในฐานะที่เป็นการแสดงออกและไม่ได้เป็นคำสั่ง นั่นคือสิ่งที่วงเล็บเสริมมีไว้สำหรับ
Pointy

16
(function(){})()เป็นที่รู้จักกันในฐานะที่เป็นIIFE (รื้อฟื้นทันที Expression ฟังก์ชั่น) ปล่อยให้มันเป็นที่รู้จักกันว่าคุณสามารถใช้สัญลักษณ์อื่น ๆ ที่จะบังคับให้แยกวิเคราะห์การรักษาฟังก์ชั่นในขณะที่การแสดงออกเช่น+,!,-,~(และอื่น ๆ ) !function($){}(jQuery)เช่นนี้ และเพื่อความสนุกสนานยิ่งขึ้นคุณสามารถ: ~~+-!function($){}(jQuery)!
David Murdoch

(ฟังก์ชัน ($, win, doc) {$ .... }) (jQuery, window, document); ฉันจะเพิ่มสิ่งนี้ด้วย ... มันช่วยให้ฉันเข้าใจดีขึ้น ด้วยความสงบสุขของรหัส jQuery ---> $; และหน้าต่าง ---> ชนะ; แล้วจัดทำเอกสาร ---> doc ... :) ขอบคุณ ...
ฮารานาด

ฉันพบตัวอย่างโค้ดที่ IMHO ไม่ได้กล่าวถึงในรายการด้านบน: $ (function () {..... } (jQuery)); (นำมาจากที่นี่: docs.microsoft.com/en-us/aspnet/core/mvc/models/… ) ที่นี่ฉันไม่เข้าใจการใช้งานของ $ ดูเหมือนจะไม่ใช่ jQuery selector $ (... ) หรือไวยากรณ์สั้น ๆ สำหรับเหตุการณ์ 'document ready' เนื่องจากฟังก์ชันไม่ส่งคืนค่าอะไรเลย ดูเหมือนว่าฉันจะไม่ได้เป็นคำนำหน้าเพื่อให้ถือว่าฟังก์ชันเป็นนิพจน์เนื่องจากอยู่นอกเครื่องหมายวงเล็บ ยิ่งไปกว่านั้นการเรียกใช้ฟังก์ชันจะถูกสร้างขึ้นภายในวงเล็บปีกกาดังนั้นเราจึงเรียกการประกาศ
sich

35

(function( $ ){

})( jQuery );

นั่นคือการเรียกใช้ฟังก์ชันที่ไม่ระบุตัวตนซึ่งใช้$ในอาร์กิวเมนต์เพื่อให้คุณสามารถใช้ ( $) แทนjQueryภายในฟังก์ชันนั้นและไม่ต้องกลัวว่าจะขัดแย้งกับไลบรารีอื่นเพราะในไลบรารีอื่นก็$มีความหมายพิเศษเช่นกัน รูปแบบนั้นมีประโยชน์อย่างยิ่งเมื่อเขียนปลั๊กอิน jQuery

คุณสามารถเขียนอักขระใดก็ได้ที่นั่นแทน$เช่นกัน:

(function(j){
  // can do something like 
  j.fn.function_name = function(x){};

})(jQuery);

ที่นี่jจะจับ jQuery ที่ระบุไว้ในตอนท้าย(jQuery)โดยอัตโนมัติ หรือคุณสามารถละทิ้งอาร์กิวเมนต์ได้อย่างสมบูรณ์ แต่จากนั้นคุณจะต้องใช้jQueryคำหลักรอบ ๆ แทน$โดยไม่ต้องกลัวว่าจะเกิดการปะทะกัน ดังนั้น$จะรวมอยู่ในอาร์กิวเมนต์สำหรับมือสั้นเพื่อให้คุณสามารถเขียน$แทนที่จะjQueryอยู่รอบ ๆ ภายในฟังก์ชันนั้น

ถ้าคุณดูซอร์สโค้ดของ jQuery ด้วยซ้ำคุณจะเห็นว่าทุกอย่างถูกรวมอยู่ระหว่าง:

(function( window, undefined ) {
  // jQuery code
})(window);

นั่นคือสิ่งที่สามารถเห็นได้นอกจากนี้ยังมีฟังก์ชั่นที่ไม่ระบุชื่อที่ดำเนินการด้วยตนเองพร้อมอาร์กิวเมนต์ window(และundefined) อาร์กิวเมนต์ถูกสร้างขึ้นและถูกแมปกับโลกวัตถุที่อยู่ด้านล่างwindow (window)รูปแบบนี้เป็นที่นิยมในปัจจุบันและมีการเพิ่มความเร็วเพียงเล็กน้อยเนื่องจากที่นี่windowจะถูกพิจารณาจากอาร์กิวเมนต์แทนที่จะเป็นwindowวัตถุส่วนกลางที่แมปไว้ด้านล่าง


$.fnเป็นวัตถุของ jQuery ที่คุณสร้างฟังก์ชั่นใหม่ของคุณ (ซึ่งเป็นวัตถุ) หรือปลั๊กอินตัวเองเพื่อให้ jQuery wraps ปลั๊กอินของคุณของ$.fnวัตถุและทำให้มันใช้ได้


ที่น่าสนใจฉันได้ตอบคำถามที่คล้ายกันที่นี่:

ไวยากรณ์ของฟังก์ชันการปิด JavaScript / jQuery

นอกจากนี้คุณยังสามารถอ่านบทความนี้เพื่อเรียนรู้เพิ่มเติมเกี่ยวกับฟังก์ชันการสั่งงานด้วยตนเองที่ฉันได้เขียนไว้:

ฟังก์ชั่นการดำเนินการด้วยตนเองของ Javascript


ดังนั้นถ้าฉันมีวัตถุชื่อ my_object และทำสิ่งนี้: (function (mo) {mo.doSomething ()}) (my_object) มันจะเรียกใช้ my_object.doSomething ()?
Ethan

3

ไวยากรณ์ปลั๊กอินพื้นฐานช่วยให้คุณใช้$เพื่ออ้างถึงjQueryในเนื้อหาของปลั๊กอินของคุณโดยไม่คำนึงถึงการระบุ$ในเวลาที่โหลดปลั๊กอิน ซึ่งจะป้องกันการตั้งชื่อที่ขัดแย้งกับไลบรารีอื่น ๆ โดยเฉพาะอย่างยิ่ง Prototype

ไวยากรณ์กำหนดฟังก์ชันที่ยอมรับพารามิเตอร์ที่เรียกว่า$เพื่อให้คุณสามารถอ้างถึงได้$ในเนื้อหาของฟังก์ชันจากนั้นเรียกใช้ฟังก์ชันนั้นทันทีโดยใส่jQueryเป็นอาร์กิวเมนต์

นอกจากนี้ยังช่วยไม่ให้เนมสเปซทั่วโลกก่อให้เกิดมลพิษ (ดังนั้นการประกาศvar myvar = 123;ในเนื้อหาปลั๊กอินของคุณจะไม่ได้กำหนดในทันทีwindow.myvar) แต่จุดประสงค์หลักที่ชัดเจนคือเพื่อให้คุณใช้ใน$ที่ที่$อาจมีการกำหนดใหม่ได้


3

คุณกำลังจัดการกับฟังก์ชันนิรนามที่เรียกตัวเองที่นั่น มันเหมือนกับ "แนวทางปฏิบัติที่ดีที่สุด" ในการรวมปลั๊กอิน jQuery ไว้ในฟังก์ชันดังกล่าวเพื่อให้แน่ใจว่า$เครื่องหมายถูกผูกไว้กับjQueryวัตถุ

ตัวอย่าง:

(function(foo) {
    alert(foo);
}('BAR'));

สิ่งนี้จะแจ้งเตือนBARเมื่อใส่ลงใน<script>บล็อก พารามิเตอร์BARถูกส่งไปยังฟังก์ชันที่เรียกตัวเอง

หลักการเดียวกันนี้เกิดขึ้นในโค้ดของคุณjQueryวัตถุจะถูกส่งผ่านไปยังฟังก์ชันดังนั้น$จะอ้างถึงวัตถุ jQuery อย่างแน่นอน


1
ฉันเข้าใจทั้งหมดนั้น สิ่งที่ฉันต้องการทราบคือเหตุใด / ไวยากรณ์ของวงเล็บจึงทำงานเพื่อสร้างฟังก์ชันการเรียกใช้งานด้วยตนเองได้อย่างไร นั่นเป็นเพียงคุณลักษณะของภาษาหรือไม่? มันทำงานอย่างไร?
เนื้อ

2

jQuery ในตอนท้ายจะส่งผ่านตัวเอง (jQuery) ไปยังฟังก์ชันเพื่อให้คุณสามารถใช้สัญลักษณ์ $ ภายในปลั๊กอินของคุณได้ คุณควรทำเช่นกัน

(function(foo){

  foo.fn.myPlugin = function() {


    this.fadeIn('normal', function(){


    });

  };
})( jQuery );

2

หากต้องการคำอธิบายที่ชัดเจนเกี่ยวกับสิ่งนี้และเทคนิคจาวาสคริปต์สมัยใหม่อื่น ๆ และแนวทางปฏิบัติทั่วไปฉันขอแนะนำให้อ่าน Javascript Garden

http://bonsaiden.github.com/JavaScript-Garden/

มีประโยชน์อย่างยิ่งเนื่องจากรูปแบบเหล่านี้มีการใช้กันอย่างแพร่หลายในห้องสมุดหลายแห่ง แต่ไม่ได้อธิบายอย่างแท้จริง


2

คำตอบอื่น ๆ ที่นี่ดีมาก แต่มีประเด็นสำคัญอย่างหนึ่งที่ยังไม่ได้รับการแก้ไข คุณพูด:

มันเป็นการสร้างฟังก์ชั่นเท่าที่ฉันบอกได้ว่าจะไม่ถูกรันด้วยพารามิเตอร์ $ ซึ่งถูกกำหนดไว้แล้ว?

ไม่มีการรับประกันว่าตัวแปรส่วนกลางไม่$สามารถใช้ได้ ตามค่าเริ่มต้น jQuery จะสร้างตัวแปรสองตัวในขอบเขตส่วนกลาง: $และjQuery(โดยที่ทั้งสองเป็นนามแฝงสำหรับวัตถุเดียวกัน) อย่างไรก็ตามjQuery ยังสามารถรันในโหมด noConflict :

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
  jQuery.noConflict();
</script>

เมื่อคุณเรียกjQuery.noConflict()ตัวแปรส่วนกลาง$จะถูกตั้งค่ากลับเป็นอะไรก็ได้ก่อนที่จะรวมไลบรารี jQuery สิ่งนี้อนุญาตให้ใช้ jQuery กับไลบรารี Javascript อื่น ๆ ที่ใช้$เป็นตัวแปรส่วนกลาง

หากคุณเขียนปลั๊กอินที่ใช้ $การเป็นนามแฝงสำหรับ jQuery ปลั๊กอินของคุณจะไม่ทำงานสำหรับผู้ใช้ที่ทำงานในโหมด noConflict

ตามที่คนอื่นได้อธิบายไปแล้วรหัสที่คุณโพสต์จะสร้างฟังก์ชันที่ไม่ระบุตัวตนซึ่งจะถูกเรียกใช้ทันที ตัวแปรส่วนกลางjQueryถูกส่งผ่านไปแล้วในฟังก์ชั่นที่ไม่ระบุชื่อนี้ซึ่ง aliased อย่างปลอดภัยเป็นท้องถิ่นตัวแปร$ภายในฟังก์ชั่น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.