Câu trả lời:
Trong jQuery, thuộc fntính chỉ là bí danh của thuộc prototypetí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.jquerylà 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",
fnnghĩ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 fnlà 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 thissẽ 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 đủ.
eachmã 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ố.
csshà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.prototypelà một đối tượng giá trị của jQuery.fnchỉ đơ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.prototypenếu đánh giá true(mà nó làm) thì họ tham chiếu cùng một đối tượng