【发布时间】:2011-06-01 04:32:03
【问题描述】:
我正在尝试为自己构建一个小助手库。首先,用于学习目的,然后我可以扩展它,以便在项目中派上用场。
我对原型引用、闭包和作用域有所了解。我还故意使用模块化模式来制作它,这样我的toolbox 就不会污染全局命名空间。
我也知道我们可以将原型分配给构造函数,因此构造的对象将保存这些方法。
这是toolbox.js的内容
(function (window) {
var toolbox = (function () {
var toolbox = function(it){
return new pick(it);
}
var pick = function (it){
var craft = document.getElementsByTagName(it);
craft = Array.prototype.slice.call(craft, 0);
return Array.prototype.push.apply(this, craft);
}
pick.prototype = toolbox.prototype = {
raw: function(){
return Array.prototype.slice.call(this, 0);
},
tell: function(secret){
return secret;
}
}
return toolbox;
}());
window.toolbox = toolbox;
})(window);
并致电toolbox:
toolbox("div"); //returns the desired object with the div collection
toolbox("div").raw(); //returns a raw array with the divs
toolbox().tell("A secret"); //returns "A secret"
toolbox.tell("It's a secret"); //type error: the function has no method like tell (like hell it does...should)
但是像这样修改上面的代码:
var toolbox = (function () {
var toolbox = function(it){
return new pick(it);
}
...
toolbox.tell(secret){ return secret }
return toolbox;
}());
会起作用。
所以我的问题是为什么toolbox.prototype = {} 不能解决问题,而pick.prototype = {} 会让pick 继承定义的方法?
我希望实现toolbox.tell("something"); 和toolbox("div").raw(); 成为可能,而无需直接将方法原型化到模块中。
请帮忙!我已经在谷歌上搜索了好几天来学习这些,现在我被困住了。非常感谢您的帮助!
更新
简而言之,jQuery 是如何做到这一点的:
(function( window, undefined ) {
var jQuery = (function() {
// 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 );
}
jQuery.fn = jQuery.prototype = {
constructor: jQuery,
init: function( selector, context, rootjQuery ) {
//init stuff
}
};
// Give the init function the jQuery prototype for later instantiation
jQuery.fn.init.prototype = jQuery.fn;
jQuery.extend = jQuery.fn.extend = function() {
//extend stuff
};
jQuery.extend({
//extend stuff
});
// Expose jQuery to the global object
return jQuery;
})();
window.jQuery = window.$ = jQuery;
})(window);
【问题讨论】:
-
prototype属性仅在构造函数中“应用”(当它成为新对象的[[prototype]]时)。这里没有toolbox的构造函数。考虑属性的手动副本:toolbox.tell = toolbox().tell等 -
可能想看看 jQuery 是如何做到这一点的。
-
@pst 感谢您的更正,我怀疑问题是工具箱没有构造函数。但是,我正在寻找一种使其自动化的解决方案。是的。像 jQuery。我可以编辑我的问题以添加一个 jQuery 示例。
-
抱歉,我不得不编辑 jQuery 示例。数百行代码难以压缩。但它现在是一个恰当的例子。
-
我不明白你对 toolbox() 的任何调用是如何工作的,因为你所有的 toolbox.js 代码都包装在一个匿名的自执行函数中(是的 - 我知道'self -executing' 不是一个完全准确的描述,但大多数人都知道是什么意思),那么这是否意味着在该函数中声明的内容对包含 toolbox.js 的页面上的代码是隐藏的?也许我只是累了。
标签: closures javascript prototype-programming scoping