将所有jQuery函数包装到一个类中

时间:2016-07-02 20:08:32

标签: javascript jquery

我想为js类包装所有jQuery's DOM函数,但是这些函数只处理该类的单个属性。

class Foo {
  constructor() {
    this.$wrapper = $('<div>wrapper</div>')
  }
}

var f = new Foo();

// have to call this
f.$wrapper.appendTo($('body'));
// want to call this
f.appendTo($('body'));

我可以通过为每个jQuery方法创建一个同名的方法手动执行此操作,这将花费很多时间,并且只需将其应用于this.$wrapper。但我想知道是否有更简单的方法来做到这一点。

https://jsfiddle.net/gy9tLyk2/

2 个答案:

答案 0 :(得分:1)

一种选择是使用ES2015代理,即Proxy构造函数。

class Foo {
  constructor() {
    this.$wrapper = $('<div>wrapper</div>');
    return new Proxy(this, {
        get: function(target, prop, receiver) {
         if ( target.hasOwnProperty(prop) ) {
           return target[prop];
         }
         return function() {
           let ret = target.$wrapper[prop](...arguments);
           if ( ret !== target.$wrapper ) return ret;
           return receiver;
         }
      }
    });
  }
}

var f = new Foo();
var a = f.appendTo($('body')).text('changed').prop('tagName');

但不建议出于以下几个原因:

  1. 浏览器支持
  2. 代理很慢
  3. jQuery有getter和setter,并且创建一个代理处理程序,而不是处理所有jQuery,并且类方法可能很棘手。

答案 1 :(得分:1)

是的,只需展开jQuery.fn.init并使用super来电:

&#13;
&#13;
class Foo extends jQuery.fn.init {
  constructor() {
    super('<div>wrapper</div>');
  }
}
Foo.prototype.constructor = jQuery;
new Foo().appendTo('body');
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
&#13;
&#13;
&#13;

注意我替换Foo.prototype.constructor因为jQuery将访问实例的constructor属性并调用它。但是像Foo这样的ES6类不可调用,jQuery不应该调用Foo

不确定babel是否能够正确转换,这是ES5代码:

&#13;
&#13;
function Foo() {
  this.init('<div>wrapper</div>');
}
Foo.prototype = Object.create(jQuery.fn);
new Foo().appendTo('body');
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
&#13;
&#13;
&#13;