我的理解是 JavaScript 中的函数可以有状态。有些状态只需要初始化一次。您如何做到这一点,以便调用函数不会重新初始化它们?
例如,jQuery 中的$()
是一个函数,而不是一个对象,但它似乎有状态并且像一个对象一样。
我考虑过为此创建一个对象,但我真正想要的是一个外观函数,很像 $()
的工作方式。
最佳答案
函数是对象。它们可以具有以下属性:
function F() {}
F.key = "value";
alert(F.key) // "value"
您还可以将函数用作构造函数,并通过 new
调用:
function F(val) { this.key = val; }
var instance = new F("value")
alert(instance.key) // "value"
如您所见,不同之处在于,第一个版本仅向 F
函数对象添加了一个 key
成员,而第二个版本初始化了一个新的 key
由 new
F
创建的每个实例 的成员。
当您通过 new
调用函数时,会自动创建一个实例对象,并且可以通过 this
关键字。默认情况下,每个构造函数都返回 this
。
您还可以将公共(public)方法添加到函数的原型(prototype)
,它们将可用于所有实例。他们可以使用 this
关键字单独更改他们的“状态”(如您所说)。
function F(val) { this.state = val; } // unique
F.prototype.change = function() { this.state = "stuff"; }
var inst = new F("value")
var inst2 = new F("value")
alert(inst.state) // "value"
alert(inst2.state) // "value"
inst.change();
alert(inst.state) // "stuff"
alert(inst2.state) // "value"
jQuery
我什至可以告诉你 jQuery 在幕后做了什么,但我认为你并不真的想知道。 :)
var jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context );
},
// ...
jQuery.fn = jQuery.prototype = {
init: function( selector, context ) {
// ...
},
// ...
};
// Give the init function the jQuery prototype for later instantiation
jQuery.fn.init.prototype = jQuery.fn;
所以基本上 $(selector)
意味着 new
jQuery.fn.init(selector)
,它只是一个更容易打字的快捷方式(也可以防止注释中提到的“错误”,其中 fogetting new
将 this
绑定(bind)到 global对象,而不是当前实例)。
此外,作为jQuery.fn.ext
添加的所谓插件被映射到jQuery.fn.init.prototype
,如您在上一节中所见行,又是一条捷径。因此,当您调用 $(selector)
时,添加到 jQuery.fn
的所有内容也将在 jQuery.fn.init.prototype
上,依此类推新实例将这些方法作为 $(selector).ext(...)
。
// as you use it today
jQuery.fn.plugin = function ( ... ) { ... }
$(selector).plugin( ... )
// as it would be without shortcuts
jQuery.fn.init.prototype.plugin = function ( ... ) { ... }
(new jQuery.fn.init(selector)).plugin( ... )
关于javascript - 如何初始化 JavaScript 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4775508/