Câu trả lời:
Trong jQuery, thuộc fn
tính chỉ là bí danh của thuộc prototype
tính.
Mã jQuery
định danh (hoặc $
) chỉ là một hàm tạo và tất cả các thể hiện được tạo bằng nó, kế thừa từ nguyên mẫu của hàm tạo.
Hàm xây dựng đơn giản:
function Test() {
this.a = 'a';
}
Test.prototype.b = 'b';
var test = new Test();
test.a; // "a", own property
test.b; // "b", inherited property
Một cấu trúc đơn giản giống với kiến trúc của jQuery:
(function() {
var foo = function(arg) { // core constructor
// ensure to use the `new` operator
if (!(this instanceof foo))
return new foo(arg);
// store an argument for this example
this.myArg = arg;
//..
};
// create `fn` alias to `prototype` property
foo.fn = foo.prototype = {
init: function () {/*...*/}
//...
};
// expose the library
window.foo = foo;
})();
// Extension:
foo.fn.myPlugin = function () {
alert(this.myArg);
return this; // return `this` for chainability
};
foo("bar").myPlugin(); // alerts "bar"
function func1 (a) { ... }
và thuộc tính sẽ là biến 'a' ở đây var foo = {}; foo.a = 'a'
.
jQuery.fn
được định nghĩa tốc ký cho jQuery.prototype
. Từ mã nguồn :
jQuery.fn = jQuery.prototype = {
// ...
}
Điều đó có nghĩa jQuery.fn.jquery
là một bí danh cho jQuery.prototype.jquery
, trả về phiên bản jQuery hiện tại. Một lần nữa từ mã nguồn :
// The current version of jQuery being used
jquery: "@VERSION",
fn
nghĩa đen là nói đến jquery prototype
.
Dòng mã này nằm trong mã nguồn:
jQuery.fn = jQuery.prototype = {
//list of functions available to the jQuery api
}
Nhưng công cụ thực sự đằng sau fn
là tính khả dụng của nó để nối chức năng của riêng bạn vào jQuery. Hãy nhớ rằng jquery sẽ là phạm vi cha mẹ cho hàm của bạn, vì vậy this
sẽ tham chiếu đến đối tượng jquery.
$.fn.myExtension = function(){
var currentjQueryObject = this;
//work with currentObject
return this;//you can include this if you would like to support chaining
};
Vì vậy, đây là một ví dụ đơn giản về điều đó. Hãy nói rằng tôi muốn tạo hai phần mở rộng, một phần mở ra một viền màu xanh lam và màu nào cho màu xanh của văn bản và tôi muốn chúng được xâu chuỗi.
jsFiddle Demo
$.fn.blueBorder = function(){
this.each(function(){
$(this).css("border","solid blue 2px");
});
return this;
};
$.fn.blueText = function(){
this.each(function(){
$(this).css("color","blue");
});
return this;
};
Bây giờ bạn có thể sử dụng những người chống lại một lớp như thế này:
$('.blue').blueBorder().blueText();
(Tôi biết điều này được thực hiện tốt nhất với css như áp dụng các tên lớp khác nhau, nhưng xin lưu ý đây chỉ là bản demo để hiển thị khái niệm)
Câu trả lời này có một ví dụ tốt về một phần mở rộng đầy đủ.
each
mã ví dụ của bạn không? $.fn.blueBorder = function(){ this.css("border","solid blue 2px"); return this; };
sẽ hoạt động tốt, như .css()
lặp đi lặp lại trên các yếu tố.
css
hàm sẽ tự động lặp lại bên trong chúng với nhau. Nó chỉ là một ví dụ cho thấy sự khác biệt trong this
đó đối tượng bên ngoài là đối tượng jquery và đối tượng bên trong tham chiếu chính phần tử đó.
Trong mã nguồn jQuery chúng tôi có jQuery.fn = jQuery.prototype = {...}
kể từ khi jQuery.prototype
là một đối tượng giá trị của jQuery.fn
chỉ đơn giản sẽ là một tham chiếu đến cùng một đối tượng mà jQuery.prototype
đã tham khảo.
Để xác nhận điều này, bạn có thể kiểm tra jQuery.fn === jQuery.prototype
nếu đánh giá true
(mà nó làm) thì họ tham chiếu cùng một đối tượng