我需要在现有的jQuery元素集合上初始化某种原型。主要问题是原型应该只能在.find()
)或该集合中的某些子对象上生成的元素上访问,例如:
var $a = $('a');
$a.__proto__.foo/*some magic over here*/ = function(){ alert('foo!'); };
$a.foo(); //should show alert('foo!')
$a.find('b').foo(); //should produce the same action
$('a').foo(); //should produce an error (method not found)
如果使用上面示例中的$a.__proto__
,则会访问jQuery.prototype
,因此该jQuery集合外部的所有新元素(例如$('a')
)都授予访问权限到.foo()
方法。在问题陈述中,这种行为是不可接受的。
这实际上是可能的吗?
答案 0 :(得分:-1)
好的,事情就是这样,我有一个相当复杂的ES6解决方案,所以我无法深入解释它,但如果你有一些特别问题,请继续。
var wrap = (function wrapper() {
var store = {};
function wrap(fn) {
return new Proxy(fn, {
apply(target, thisArg, argumentsList) {
var result = Reflect.apply(target, thisArg, argumentsList);
// `jQuery(...)` returns a "rich" object that always contain `.length`
if (result.length > 0) {
result = new Proxy(result, {
get(target, propertyKey, receiver) {
var value = Reflect.get(target, propertyKey, receiver);
if (Object.keys(store).includes(propertyKey)) {
value = store[propertyKey];
}
return value;
},
set(target, propertyKey, value, receiver) {
// TODO: use `Reflect.set(), somehow`
// return Reflect.set(store, propertyKey, value, receiver);
return (store[propertyKey] = value);
},
});
}
return result;
}
});
}
return wrap;
})();
var $ = wrap(jQuery);
$.prototype.find = wrap(jQuery.prototype.find); // TODO: implement recursively in `wrap()`
var x = $('div');
var xx = x.find('div');
var xxx = x.find('divvv');
xx.foo = 123;
console.log(x.foo); // 123
console.log(xx.foo); // 123
console.log(xxx.foo); // undefined