如何将js对象用作函数AND对象和原型方法

时间:2015-07-15 10:27:31

标签: javascript prototype

用例类似于“How can I use an object as a function and an object?

我目前的解决方案:

var newObj = function(_id){
  var obj = function(arg){
    console.log('call', _id, arg);
  }
  obj.test = function(arg){
    console.log('test', _id, arg);
  }
  console.log('new', _id);
  return obj
}

var obj = newObj('1');
obj('2');
obj.test('3');

现在,如果你的对象数量很少,这种方法很有效。

但是,当你获得大量方法和大量对象时,你需要将所有方法都移动到原型。怎么可能呢?

天真的解决方案,像这样:

var Obj = function(id){
  this.id = id
  console.log('new',id)
}
Obj.prototype = function(arg){
  console.log('call', this.id, arg)
}
Obj.prototype.test = function(arg){
  console.log('test', this.id, arg)
}
var obj = new Obj('1');
obj('2'); // this fails with "TypeError: obj is not a function"
obj.test('3');

不起作用。

修改 最终目标是缩短对象最常用方法的语法。

例如:bus对象有方法post。当您使用bus执行某项操作时,此方法称为99.99%的时间。始终写bus.post(...)是多余的。创建闭包或绑定也不是一种选择,因为有很多总线。

当前的解决方案(没有原型)工作正常,只有少量的对象。

1 个答案:

答案 0 :(得分:1)

你无法直接做你想做的事。函数是一个函数,具有函数原型。你可以做的是在每个函数上放置一个对象作为属性,并通过它调用你的例程。

这将使用如下:

var obj = newObj('1');
obj('2');
obj.methods.test('3');
    ^^^^^^^ INVOKE VIA METHODS PROPERTY

你可以把它想象成一种手工制作的原型。

现在我们将安排methods属性返回正确绑定到此的函数哈希,例如允许访问id。为了解决这个问题,我们将methods作为gettable属性添加到函数中,返回方法的哈希值,每个方法都绑定到正确的:

var Obj = function(id){
  this.id = id
  console.log('new',id)
  Object.defineProperty(this, 'methods', {
    get: function() { return methods(this); }
  });
}

现在将methods定义为

function methods(obj) {
  return {
    test: function(arg) {
      console.log('test', this.id, arg);
    }.bind(obj)
};

现在单个函数对象上唯一的足迹是单个methods属性。其他一切都是共享的。但是,调用methods函数存在每次访问的运行时成本。你不能两种方式:要么你可以预先绑定并将方法放在每个对象上,要么在访问methods时可以进行后期绑定。