【问题标题】:JavaScript clustered methods in sub-objects子对象中的 JavaScript 集群方法
【发布时间】:2013-05-27 19:16:26
【问题描述】:

这是一个例子:

var Bidule = function() {
    this.value = 8 ;

    this.calc = {
        plus : function(x) { return this.value + x ; },
        minus : function(x) { return this.value - x ; },
        square : function() { return this.value * this.value ; }
    }

    this.fn = {
        random : {
            set : function() { return this.value = random() ; },
            add : function() { return this.value += random() ; }
        }
    }
} ;

var b = new Bidule() ;
console.log(b.value) ;            // 8
console.log(b.calc.plus(4)) ;     // Error : 'this.value' is undefined.
console.log(b.fn.random.add()) ;  // Error : 'this.value' is undefined.

关键是要有集群方法,因为它在我看来比 'b.fn_random_add()' 更优雅。

修复“this”引用很容易:

var _plus = b.calc.plus ;
b.calc.plus = function() {
    return _plus.apply(b, arguments) ;
} ;

console.log(b.calc.plus(4)) ;     // 12

但是之前的“this.calc.plus”和新的集合都没有在 Bidule 的原型中。

我想过让子对象有自己的原型,比如:

this.calc = new Bidule_calc ;

但我无法设置主对象“this”引用。

除了...还有其他方法吗:

b.calc.plus.call(b, 4) ;

...设置和调用集群方法?


在我写这篇文章的时候,我发现了一个可能的解决方案:

var context = this ;
Object.defineProperty(this.calc, 'value', {
    get : function() {
        return context.value ;
    }
}) ;

但是,仍然存在无用重复函数的问题,因为原型中没有“this.calc”,并且将为 Bidule 的每个实例调用“Object.defineProperty”,因此将创建重复函数以覆盖聚类方法。


编辑: 我必须准确地说,我们必须为所有方法使用原型:

var Bidule = function() {
    this.value = 8 ;
} ;
Bidule.prototype = {
    getValue : function() { return this.value ; }
} ;

不过,Bidule 的构造函数和原型有两个独立的作用域。 这意味着我们不能将任何“var”共享到构造函数中以共享给方法。

【问题讨论】:

  • 一个快速的“修复”是在主函数的顶部声明var that = this;,然后在需要引用所有者Bidule 时在所有子模块中引用that。其次,没有random()方法,所以你不能只做= random() ;,所以你的fn.random.setfn.random.add不起作用
  • 您是否有理由希望您的方法像这样嵌套?由于this 问题,这不是典型的JavaScript 习惯用法。为什么不直接把它们放在Bidule.prototype 上呢?然后你可以做b.plus(4)
  • @Lan : 我知道random() 不存在,只是举个简单的例子。嗯...我知道在变量中设置this 会起作用,但原型无法访问私有变量that。 @Crazy Train:我知道这并不典型,但我发现这个问题和实现这个问题的方式都很有趣。我想听听别人的答案和观点。

标签: javascript object methods


【解决方案1】:

只需将要使用的范围保存到变量中。在 JSFiddle 中测试。

var Bidule = function() {
    var self = this;
    this.value = 8 ;

    this.calc = {
        plus : function(x) { return self.value + x ; },
        minus : function(x) { return self.value - x ; },
        square : function() { return self.value * self.value ; }
    }

    this.fn = {
        random : {
            set : function() { return self.value = random() ; },
            add : function() { return self.value += random() ; }
        }
    }
} ;

【讨论】:

  • 是的,它会起作用的。但是,您的构造函数不使用原型:var Bidule = function() { var self = this ; ... } ; Bidule.prototype = {} ;。这里原型不会访问var self。我们可以这样放置原型:var Bidule = function() { var self = this ; this.prototype = { ... } ; },但这意味着每次调用构造函数时都会设置原型,所以这也不是一个好方法。
  • 我能想到的唯一方法就是让 fn 成为一个返回对象的函数。见我的 jsfiddle jsfiddle.net/txANC
  • 是的,确实是一个很好的方法。但是,我们必须像您的示例一样对其进行改进,fn() 将在每次调用时构建这些方法。但也许有一种方法可以将 'fn' 中的集群方法导出到外部并仅返回一个引用。
猜你喜欢
  • 2021-09-18
  • 2021-09-26
  • 1970-01-01
  • 1970-01-01
  • 2015-04-23
  • 1970-01-01
  • 2011-08-05
  • 2020-11-24
  • 1970-01-01
相关资源
最近更新 更多