Antworten:
In jQuery ist die fnEigenschaft nur ein Alias für die prototypeEigenschaft.
Der jQueryBezeichner (oder $) ist nur eine Konstruktorfunktion , und alle damit erstellten Instanzen erben vom Prototyp des Konstruktors.
Eine einfache Konstruktorfunktion:
function Test() {
this.a = 'a';
}
Test.prototype.b = 'b';
var test = new Test();
test.a; // "a", own property
test.b; // "b", inherited property
Eine einfache Struktur, die der Architektur von jQuery ähnelt:
(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"
return thisum Verkettung zu ermöglichen , so könnten Sie tunfoo("bar").myPlugin().otherPlugin()
function func1 (a) { ... }, und eine Eigenschaft wäre hier die Variable 'a' var foo = {}; foo.a = 'a'.
jQuery.fnist eine Kurzform für jQuery.prototype. Aus dem Quellcode :
jQuery.fn = jQuery.prototype = {
// ...
}
Das heißt, es jQuery.fn.jqueryhandelt sich um einen Alias für jQuery.prototype.jquery, der die aktuelle jQuery-Version zurückgibt. Wieder aus dem Quellcode :
// The current version of jQuery being used
jquery: "@VERSION",
fnbezieht sich wörtlich auf die Abfrage prototype.
Diese Codezeile befindet sich im Quellcode:
jQuery.fn = jQuery.prototype = {
//list of functions available to the jQuery api
}
Das eigentliche Werkzeug dahinter fnist jedoch die Verfügbarkeit, um Ihre eigenen Funktionen in jQuery einzubinden. Denken Sie daran, dass jquery der übergeordnete Bereich Ihrer Funktion ist und sich daher thisauf das jquery-Objekt bezieht.
$.fn.myExtension = function(){
var currentjQueryObject = this;
//work with currentObject
return this;//you can include this if you would like to support chaining
};
Hier ist ein einfaches Beispiel dafür. Nehmen wir an, ich möchte zwei Erweiterungen erstellen, eine, die einen blauen Rand setzt und die den Text blau färbt, und ich möchte, dass sie verkettet werden.
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;
};
Jetzt können Sie diese gegen eine Klasse wie diese verwenden:
$('.blue').blueBorder().blueText();
(Ich weiß, dass dies am besten mit CSS möglich ist, z. B. mit dem Anwenden verschiedener Klassennamen, aber bitte denken Sie daran, dass dies nur eine Demo ist, um das Konzept zu zeigen.)
Diese Antwort enthält ein gutes Beispiel für eine vollwertige Erweiterung.
eachCode in Ihrem Beispielcode nicht einfach überspringen ? $.fn.blueBorder = function(){ this.css("border","solid blue 2px"); return this; };würde gut funktionieren, da .css()alerady über die Elemente iteriert.
cssFunktion diese bei jedem automatisch intern durchlaufen. Es war nur ein Beispiel für die Darstellung der Unterschiede, bei thisdenen das äußere das Abfrageobjekt ist und das innere auf das Element selbst verweist.
Im jQuery-Quellcode, den wir haben, jQuery.fn = jQuery.prototype = {...}da jQuery.prototypees sich um ein Objekt handelt, ist der Wert von jQuery.fneinfach ein Verweis auf dasselbe Objekt wiejQuery.prototype bereits verwiesen wird.
Um dies zu bestätigen, können Sie überprüfen, jQuery.fn === jQuery.prototypeob dies ausgewertet wird true(was es tut), dann verweisen sie auf dasselbe Objekt