我在工作中有这个微库,就像一个轻量级的jQuery(让我们称之为kQuery)。
以下是一些删节代码:
(function(_){
var dom_obj,
ret_obj;
var kQuery = function(selector, context, undefined){
dom_obj = new Dom(selector, context, undefined);
ret_obj = dom_obj.core;
ret_obj.__proto__ = dom_obj.constructor.prototype;
return ret_obj;
};
function Dom(selector, context, undefined)
{
var el;
el = document.querySelectorAll(selector);
this.core = [];
var payload = (_.count(el) === 1) ? el[0] : el;
this.core.push(payload);
this.core.context = window.document;
this.core.selector = selector;
}
Dom.prototype.each = function(callback){
//my each method code
};
Dom.prototype.find = function(selector)
{
//my find method code
};
Dom.prototype.addClass = function(class_name)
{
//my addClass method code
};
//assign to window object
window.kQuery = kQuery;
//assign to $ namespace if it is undefined
window.$ = window.$ || window.kQuery;
})(_);
注意:_
不是下划线,只是非常相似的东西。
上面的代码有效[并且通过工作,我的意思是它创建了一个类似于数组的对象,非常类似于jQuery创建的对象,例如: $('#element_id')
)],但我已经读过使用__proto__
这种方式可能不是最好的(反模式而不是跨浏览器)。
是否有另一种方法可以在跨浏览器[ie8基线]方式中重写ret_obj.__proto__ = dom_obj.constructor.prototype;
?
答案 0 :(得分:1)
在这种情况下,您应该使用Object.create
。
ret_obj = Object.create(dom_obj.constructor.prototype, dom_obj.core)
答案 1 :(得分:1)
我看到你能做到这一点的唯一方法是在IE 8中创建一个新的Object(使用new
运算符),然后在构造函数中将dom_obj.core
的属性赋值给它: / p>
var kQuery = function(selector, context, undefined){
dom_obj = new Dom(selector, context, undefined);
function ret_obj_proto (domob) {
for(var item in domob) {
if(Object.prototype.hasOwnProperty.call(domob, item)) { // Check if it is an own property, IE 8 style
this[item] = domob[item];
}
}
};
ret_obj_proto.prototype = dom_obj.constructor.prototype;
ret_obj = new ret_obj_proto(dom_obj);
return ret_obj;
};
我很好奇是否有更好的解决方案。
答案 2 :(得分:0)
如果您在ES6环境中,请使用Object.setPrototypeOf
:
Object.setPrototypeOf(ret_obj, dom_obj.constructor.prototype)
答案 3 :(得分:0)
我能够解决这个问题:
{{ form_widget(form.timespan, {'attr': {'class': 'span2'}}) }}
一旦对象已经创建,改变(function(_){
if (!Object.create)
{
Object.create = function(o, properties)
{
if (typeof o !== 'object' && typeof o !== 'function')
{
throw new TypeError('Object prototype may only be an Object: ' + o);
}
else if (o === null)
{
throw new Error("This browser's implementation of Object.create is a shim and doesn't support 'null' as the first argument.");
}
/*jshint -W116 */
if (typeof properties != 'undefined')
{
throw new Error("This browser's implementation of Object.create is a shim and doesn't support a second argument.");
}
/*jshint +W116 */
function F() {}
F.prototype = o;
return new F();
};
}
function merge( first, second )
{
var len = +second.length,
j = 0,
i = first.length;
while ( j < len ) {
first[ i++ ] = second[ j++ ];
}
// Support: IE<9
// Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
if ( len !== len ) {
while ( second[j] !== undefined ) {
first[ i++ ] = second[ j++ ];
}
}
first.length = i;
return first;
}
var init_dom_obj,
dom_obj;
var kQuery = function(selector, context, undefined){
init_dom_obj = new initDom(selector, context, undefined);
dom_obj = new Dom();
dom_obj = merge(dom_obj, init_dom_obj.core);
dom_obj.context = init_dom_obj.context;
dom_obj.selector = init_dom_obj.selector;
return dom_obj;
};
function Dom(){}
Dom.prototype = Object.create(Array.prototype);
function initDom(selector, context, undefined)
{
var el;
el = document.querySelectorAll(selector);
this.core = [];
var payload = (_.count(el) === 1) ? el[0] : el;
this.core.push(payload);
this.context = window.document;
this.selector = selector;
}
Dom.prototype.each = function(callback){
//my each method code
};
Dom.prototype.find = function(selector)
{
//my find method code
};
Dom.prototype.addClass = function(class_name)
{
//my addClass method code
};
//assign to window object
window.kQuery = kQuery;
//assign to $ namespace if it is undefined
window.$ = window.$ || window.kQuery;
})(_);
[我最初尝试这样做的方式]是有问题的,我认为以迂回方式做事情会更好:
__proto__
]以及来自get-go的所有必需方法Dom
]与我们的主init_dom_obj.core
对象合并(可行,因为它们都是数组)希望如果您正在构建一个微型库或类似的东西,这会有所帮助。