2017-03-16 136 views
0

我需要在已經存在的jQuery元素集合上初始化某種原型。主要的問題是,原型應該是隻能訪問內該集合,並通過內置的jQuery功能,如.find()上收集或一些子對象該集合的內部,例如生產要素:創建jQuery原型集合

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()方法。這種行爲在問題陳述上是不可接受的。

這實際上可能嗎?

回答

-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 
+0

爲什麼倒票?我認爲這是非常合理的解決方案 – zhirzh

+0

_That downvote不是我的one._我需要本地JavaScript(ES5)的解決方案,我需要**子**來繼承新的屬性,而不是父類,就像你的例子('x ,xx')。 – impulsgraw

+0

在純ES5中實現解決方案的難度極大。我確信,使用[高階函數](https://www.sitepoint.com/higher-order-functions-javascript/)的一些令人費解的代碼可能能夠做到這一點,但**不會**以您期望的方式它。你必須使用setter和getter方法,而不是使用HOFs的簡單屬性。 – zhirzh