我刚刚看到John Resig提出的谷歌技术讲座,他说jQuery作为一个阵列运行。按照这个建议,我一直在玩一个子类数组,它工作得很好但是我一直在查看jQuery源代码并且看不到它们使用了相同的方法
jQuery.prototype = new Array();
我甚至无法看到它使用调用/ apply的原生Array.prototype.methods或窗口中的原型链。$ object,所以我想知道jQuery对象如何返回所选的数组元件。
我尝试过使用普通对象,但是如果返回一个数组就会停止链接命令的能力
如果可以从Array.prototype中获取一些返回数组的必要方法吗?
这就是我正在玩的东西。
;(function(window, document, undefined){
function MyLib(){};
// prototype constructor functions
function Core(){};
function Methods(){};
// create new instance of the MyLib object and call the construct method
function myLib(selector){
return new MyLib().construct(selector);
}
// allow adding new methods to the prototype from the window.
// eg $.extend('module', 'name', 'function')
myLib.extend = function(module, name, fn){
if(typeof fn === 'function'){
if(!MyLib.prototype[module][name]){
MyLib.prototype[module][name] = fn;
}
} else if(typeof fn === 'object'){
for(var key in fn){
if(!MyLib.prototype[module][key]){
MyLib.prototype[module][key] = fn[key];
}
}
} else {
throw new Error("invalid type, function or objects are required");
}
}
MyLib.prototype = new Array();
MyLib.prototype.core = new Core();
MyLib.prototype.methods = new Methods();
MyLib.prototype.construct = function(selector){
var elems = document.getElementsByTagName(selector);
Array.prototype.push.apply(this, Array.prototype.slice.call(elems, 0, elems.length));
return this;
};
// access to prototype objects with $.core && $.methods
myLib.core = MyLib.prototype.core;
myLib.methods = MyLib.prototype.methods;
// give the window access to the constructor function
window.$ = myLib;
// give the window access to the prototype object for debugging
window.$$ = MyLib;
})(window, document);
// this adds a new method to the methods object within the prototype
$.extend('methods', 'test', function(){alert('method successfully added')});
// the added method can be accessed with
$.methods.test();
// or
$('tagName').test();
感谢您的回答
答案 0 :(得分:4)
要“作为一个数组”工作(我们通常说的是“类数组”对象),你不会继承Array
,你只需要
length
"0"
,"1"
... length-1
(您可以跳过一些)示例:
var a = {
length: 2,
"0": 'first',
"1": 'second'
}
var b = [].slice.call(a); // yes, Array functions work !
console.log(b); // logs ["first", "second"]
当然,通过定义基于原型的类和相关的原型函数(就像jQuery一样),您可以使lib用户更容易:
var A = function(){
this.length = 2;
this['0'] = 'first';
this['1'] = 'second';
}
A.prototype.slice = [].slice;
A.prototype.splice = [].splice;
var a = new A, b = a.slice();
console.log(a); // logs ["first", "second"] because of the splice function
console.log(Array.isArray(a));
console.log(b); // logs ["first", "second"] because it's really an array
console.log(Array.isArray(b)); // true
如果您希望将对象记录为数组,则需要具有splice
功能。