Cái gì (hàm ($) {}) (jQuery); nghĩa là?


299

Tôi chỉ mới bắt đầu với việc viết các plugin jQuery. Tôi đã viết ba plugin nhỏ nhưng tôi chỉ đơn giản là sao chép dòng vào tất cả các plugin mà không thực sự biết ý nghĩa của nó. Ai đó có thể cho tôi biết thêm một chút về những điều này? Có lẽ một lời giải thích sẽ có ích vào một ngày nào đó khi viết một khung :)

Cái này làm gì (Tôi biết nó mở rộng jQuery bằng cách nào đó nhưng có gì thú vị khác để biết về điều này)

(function($) {

})(jQuery);

Sự khác biệt giữa hai cách viết plugin sau đây là gì:

Loại 1:

(function($) {
    $.fn.jPluginName = {

        },

        $.fn.jPluginName.defaults = {

        }
})(jQuery);

Loại 2:

(function($) {
    $.jPluginName = {

        }
})(jQuery);

Loại 3:

(function($){

    //Attach this new method to jQuery
    $.fn.extend({ 

        var defaults = {  
        }  

        var options =  $.extend(defaults, options);  

        //This is where you write your plugin's name
        pluginname: function() {

            //Iterate over the current set of matched elements
            return this.each(function() {

                //code to be inserted here

            });
        }
    }); 
})(jQuery);

Tôi có thể rời khỏi đây và có lẽ tất cả đều có nghĩa tương tự. Tôi bị bối rối. Trong một số trường hợp, điều này dường như không hoạt động trong một plugin mà tôi đang viết bằng Loại 1. Cho đến nay, Loại 3 có vẻ thanh lịch nhất đối với tôi nhưng tôi cũng muốn biết về những người khác.


22
Nó giường thời gian ở đây, nhưng chỉ dành riêng cho người mới bắt đầu, (function($) { })(jQuery);kết thúc tốt đẹp mã để $jQuerybên trong đóng cửa đó, ngay cả khi $phương tiện cái gì khác bên ngoài của nó, thường là kết quả của $.noConflict()ví dụ. Điều này đảm bảo plugin của bạn hoạt động, dù có hay không $ === jQuery :)
Nick Craver

3
Về (function($) { })(jQuery)bạn đã nói: "Tôi biết nó mở rộng jQuery bằng cách nào đó [...]". Rõ ràng bạn không biết vì tuyên bố của bạn là sai 100%. Bằng cách này, nó có thể gây hiểu lầm cho độc giả tương lai. Hãy xem cái này: stackoverflow.com/a/32550649/1636522 .

Mở rộng nhận xét của @ NickCraver, jquery-ui-1.7.2.custom.min.js sử dụng ví dụ này: jQuery.ui || (function (c) {var i = c.fn.remove, d = c.browser. mozilla ........}) (jQuery);. Tôi biết rằng đó là một phiên bản cũ của Giao diện người dùng jQuery với mã không dùng nữa, nhưng vấn đề là cho thấy trong trường hợp đó, họ đang sử dụng "c" thay vì "$".
Jaime Montoya

Câu trả lời:


234

Thứ nhất, một khối mã trông giống như (function(){})()chỉ là một chức năng được thực thi tại chỗ. Hãy phá vỡ nó một chút.

1. (
2.    function(){}
3. )
4. ()

Dòng 2 là một hàm đơn giản, được gói trong ngoặc đơn để báo cho bộ thực thi trả lại hàm cho phạm vi cha, một khi hàm trả về được thực thi bằng dòng 4, có thể đọc qua các bước này sẽ giúp ích

1. function(){ .. }
2. (1)
3. 2()

Bạn có thể thấy 1 là khai báo, 2 là trả về hàm và 3 chỉ thực thi hàm.

Một ví dụ về cách nó sẽ được sử dụng.

(function(doc){

   doc.location = '/';

})(document);//This is passed into the function above

Đối với các câu hỏi khác về plugin:

Loại 1: Đây thực sự không phải là một plugin, nó là một đối tượng được truyền dưới dạng hàm, vì các plugin có xu hướng là các hàm.

Loại 2: Đây lại không phải là một plugin vì nó không mở rộng $.fnđối tượng. Nó chỉ là một phần mở rộng của lõi jQuery, mặc dù kết quả là như nhau. Đây là nếu bạn muốn thêm các chức năng truyền tải như toArray, v.v.

Loại 3: Đây là phương pháp tốt nhất để thêm plugin, nguyên mẫu mở rộng của jQuery lấy một đối tượng giữ tên và chức năng plugin của bạn và thêm nó vào thư viện plugin cho bạn.


2
Nếu bạn đọc câu hỏi ban đầu, OP chỉ định 3 phương pháp viết đóng, anh ta đặt tên cho các phương thức đó là {1,2,3}, tôi thực sự đang đề cập đến các lĩnh vực trong câu hỏi bằng một câu trả lời ..
RobertPitt

1
(function () {}) có nghĩa là trả về hàm bên trong? Chính xác thì "()" nghĩa là gì?
Jaskey 2/2/2015

Tôi thích ví dụ đầu tiên là ví dụ thứ hai sử dụng tham chiếu số dòng (không phải là tính năng js) không rõ ràng.
Samy Bencherif

1
Cái đó được gọi là Biểu hiện chức năng được gọi ngay lập tức (IIFE): benalman.com/news/2010/11/iêu
Andres Rojas

1
Tôi có hầu hết các vấn đề hiểu dấu ngoặc đơn bên ngoài của ( function(){} ): Đây chính xác là gì? Tôi có thể không chỉ viết function(){}()?
TMOTTM

127

Ở cấp độ cơ bản nhất, một cái gì đó của hình thức (function(){...})()là một chức năng theo nghĩa đen được thực thi ngay lập tức. Điều này có nghĩa là bạn đã xác định một chức năng và bạn đang gọi nó ngay lập tức.

Biểu mẫu này hữu ích cho việc ẩn và đóng gói thông tin vì mọi thứ bạn xác định bên trong hàm đó vẫn là cục bộ của hàm đó và không thể truy cập được từ thế giới bên ngoài (trừ khi bạn phơi bày cụ thể - thường thông qua một đối tượng được trả lại theo nghĩa đen).

Một biến thể của dạng cơ bản này là những gì bạn thấy trong các trình cắm jQuery (hoặc trong mẫu mô-đun này nói chung). Vì thế:

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

Điều đó có nghĩa là bạn đang chuyển tham chiếu đến jQueryđối tượng thực tế , nhưng nó được gọi là $trong phạm vi của hàm theo nghĩa đen.

Loại 1 không thực sự là một plugin. Bạn chỉ đơn giản là gán một đối tượng theo nghĩa đen jQuery.fn. Thông thường, bạn gán một hàm cho các jQuery.fnplugin thường chỉ là các hàm.

Loại 2 tương tự như Loại 1; bạn không thực sự tạo ra một plugin ở đây. Bạn chỉ đơn giản là thêm một đối tượng theo nghĩa đen jQuery.fn.

Loại 3 là một plugin, nhưng nó không phải là cách tốt nhất hoặc dễ nhất để tạo một plugin.

Để hiểu thêm về điều này, hãy xem câu hỏicâu trả lời tương tự này . Ngoài ra, trang này đi vào một số chi tiết về các plugin tác giả.


1
Tôi không chắc chắn làm thế nào Loại 3 đang mở rộng lõi. Đây là cách hoàn toàn hợp lệ để tạo plugin vì bạn đang mở rộng nguyên mẫu. Mặc dù một chút không cần thiết.
tbranyen

1
Xấu của tôi - tôi nên đã rõ ràng hơn. Tôi đã vội vàng và bạn là chính xác.
Vivin Paliath

32

Một sự giúp đỡ nho nhỏ:

// an anonymous function
  
(function () { console.log('allo') });

// a self invoked anonymous function

(function () { console.log('allo') })();
  
// a self invoked anonymous function with a parameter called "$"
  
var jQuery = 'I\'m not jQuery.';

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


21

Chỉ cần bổ sung nhỏ để giải thích

Cấu trúc (function() {})();này được gọi là IIFE (Biểu thức hàm được gọi ngay lập tức), nó sẽ được thực thi ngay lập tức, khi trình thông dịch sẽ đạt đến dòng này. Vì vậy, khi bạn viết những hàng này:

(function($) {
  // do something
})(jQuery);

điều này có nghĩa là, trình thông dịch sẽ gọi hàm ngay lập tức và sẽ chuyển jQuerynhư một tham số, sẽ được sử dụng bên trong hàm như $.


12

Trên thực tế, ví dụ này đã giúp tôi hiểu (function($) {})(jQuery);ý nghĩa của nó.

Xem xét điều này:

// Clousure declaration (aka anonymous function)
var f = function(x) { return x*x; };
// And use of it
console.log( f(2) ); // Gives: 4

// An inline version (immediately invoked)
console.log( (function(x) { return x*x; })(2) ); // Gives: 4

Và bây giờ hãy xem xét điều này:

  • jQuery là một biến giữ đối tượng jQuery.
  • $là một tên biến giống như bất kỳ khác ( a, $b, a$bvv) và nó không có bất kỳ ý nghĩa đặc biệt như thế nào trong PHP.

Biết rằng chúng ta có thể có một cái nhìn khác về ví dụ của chúng tôi:

var $f = function($) { return $*$; };
var jQuery = 2;
console.log( $f(jQuery) ); // Gives: 4

// An inline version (immediately invoked)
console.log( (function($) { return $*$; })(jQuery) ); // Gives: 4

Đối với tôi, đây là câu trả lời tốt nhất. rõ ràng và đơn giản
Saleh

11

Loại 3, để làm việc sẽ phải như thế này:

(function($){
    //Attach this new method to jQuery
    $.fn.extend({     
        //This is where you write your plugin's name
        'pluginname': function(_options) {
            // Put defaults inline, no need for another variable...
            var options =  $.extend({
                'defaults': "go here..."
            }, _options);

            //Iterate over the current set of matched elements
            return this.each(function() {

                //code to be inserted here

            });
        }
    }); 
})(jQuery);

Tôi không chắc tại sao ai đó sẽ sử dụng mở rộng chỉ bằng cách trực tiếp thiết lập thuộc tính trong nguyên mẫu jQuery, nó đang làm điều tương tự chính xác chỉ trong các hoạt động nhiều hơn và lộn xộn hơn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.