使用例如Chrome开发者工具,我们可以轻松检查JavaScript / jQuery对象。我想了解以下内容:
$.ajax // defined as 'function ...'
$.fn.ajax // undefined
$.removeClass // undefined
$.fn.removeClass // defined
由于未定义$.removeClass
,我们如何调用,例如$('body').removeClass('some-class')
?而且,这会导致错误$('body').fn.removeClass('some-class')
?
答案 0 :(得分:3)
您询问的是两种不同类型的物品。
$
与jQuery
相同,是一个具有属性的函数。 $.ajax
是其中一个属性。
$('body')
创建的实际jQuery对象实际上是jQuery.fn.init
不是jQuery
的实例的对象。
所以,这是你在$
和$('body')
上看到不同方法的第一个原因,因为它们是不同类型的对象,因此可以有不同类型的方法。
为了进一步理解,$
上的方法(jQuery
的同义词)是直接添加到jQuery
函数本身的方法。在jQuery代码中,这主要是在jQuery对象上使用jQuery.extend()
完成的。 $.ajax
就是其中之一。
jQuery函数创建的jQuery对象上的方法是分配给jQuery.fn.init.prototype
的方法,由于jQuery的一些技巧,这些方法是分配给jQuery.fn
的方法。事实证明jQuery.fn.init.prototype
设置为与jQuery.fn
相同的对象,因此当任何内容分配给jQuery.fn
时,它会自动转到jQuery.fn.init.prototype
,并且该原型上的任何内容都会自动变为jQuery.fn.init
jQuery('body')
对象的方法,它是由jQuery函数创建的,如$('body')
或jQuery.fn.init
。
您可以在jQuery代码中看到这一点。如果你看一下jQuery函数,它看起来像这样(它创建一个jQuery.fn.init.prototype
的对象,因此将有// Define a local copy of jQuery
var jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context, rootjQuery );
},
的方法:
.fn
然后,// Give the init function the jQuery prototype for later instantiation
jQuery.fn.init.prototype = jQuery.fn;
就像这样:
jQuery.fn
分配给jQuery.fn.init.prototype
的任何方法也在{{1}}上,并成为jQuery对象的方法。
答案 1 :(得分:2)
当您执行var el = $("#content");
之类的操作时,您正在处理几种不同类型的对象:
"#content"
。 '努夫说。$
(此处为jQuery
的同义词)是一个功能。您正在使用字符串"#content"
调用它,如上所述。jQuery
函数创建jQuery对象。 el
是其中一个对象。 jQuery
函数及其直接附加属性大部分都不适用于任何特定元素;他们是你可能想要自己做的事情。举个例子,jQuery.ajax
;这不适用于某个元素,所以它直接放在jQuery
函数上。
当您获得应用操作的元素的上下文时,其他功能才有意义。比如说,删除一个类。如果我说jQuery.removeClass("selected");
,我想从中删除该课程?你从未指定过,所以你不能这样做。相反,假设我们如上所述分配el
,el.removeClass("selected");
确实有意义;它从el
表示的任何元素中删除一个类(此处为ID为content
的元素)。
每当我们在点之后有这些函数名之一时,它就是点之前的某个属性(直接或间接)。如果ajax
等函数不涉及任何元素,则会直接放在$
/ jQuery
上。对于像removeClass
这样的方法,它会放在所有jQuery
个对象上。
当然,如果您想要添加一个可以在removeClass
等元素上使用的新方法,那么将该属性添加到每个元素都会相当繁琐,更不用说获取对过去,现在和未来的每个jQuery对象的引用!因此,jQuery.fn
是一个对象,充当所有jQuery对象的原型。这意味着无论何时创建一个新的jQuery对象,它都会像它所基于的原型jQuery.fn
一样起到最小的作用。如果向jQuery.fn
添加属性,它将出现在所有jQuery对象上。事实上,原型的概念深深地嵌入到JavaScript中,修改jQuery.fn
将影响所有 jQuery对象,无论它们是新创建的,过去创建的还是创建的。将来
答案 2 :(得分:0)
我对jQuery很新,但我的理解是$ .fn是一个包含可以在jQuery对象上调用的所有方法的属性。
这就是为什么当你write a plugin时,你通过添加你自己的函数定义来扩展$ .fn。
答案 3 :(得分:0)
在JavaScript中声明函数时,它是一个对象:
function foo() {...}
foo.bar = 'baz'; //set the `bar` property on `foo`
......以及作为构造函数:
var f = new foo();
f instanceof foo; //`true`
f.bar; //undefined
从函数构造对象时,实例将从其构造函数的prototype
继承属性:
function Bar() {...}
Bar.prototype = {
baz: function () {
console.log('baz');
}
}
var b = new Bar();
b.baz(); //logs 'baz'
Bar.baz(); //error
此外,JavaScript中的对象通过引用*。
传递var fizz,
buzz;
fizz = {};
buzz = fizz;
buzz.foo = 'bar';
console.log(fizz.foo); //logs 'bar'
jQuery工厂函数(jQuery
或$
)基本上是按以下方式定义的:
function jQuery(...args...) {
//the map returned is a jQuery init object
return new jQuery.init(...args...);
}
//jQuery.init is a function used as a constructor
jQuery.init = function () {...do stuff...};
//jQuery.init.prototype is an object containing the methods that can be called on
//jQuery.init objects
jQuery.init.prototype = {
addClass: function () {...},
on: function () {...},
removeClass: function () {...}
};
//The jQuery.init.prototype object is exposed via jQuery.fn
jQuery.fn = jQuery.init.prototype;
//functions available on the jQuery namespace are added to the jQuery function object.
jQuery.ajax = function () {};
jQuery.extend = function () {};
* sorta
**总超额预估