Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/417.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
子对象中的JavaScript集群方法_Javascript_Object_Methods - Fatal编程技术网

子对象中的JavaScript集群方法

子对象中的JavaScript集群方法,javascript,object,methods,Javascript,Object,Methods,以下是一个例子: 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 ;

以下是一个例子:

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”不在原型中,并且“Object.defineProperty”将为Bidule的每个实例调用,因此将创建复制函数以覆盖集群方法


编辑: 我必须明确指出,我们必须为所有方法使用原型:

var Bidule = function() {
    this.value = 8 ;
} ;
Bidule.prototype = {
    getValue : function() { return this.value ; }
} ;
尽管如此,Bidule的构造函数和原型有两个独立的范围。
这意味着我们不能将任何“var”共享到构造函数中,以共享给方法。

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

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=this位于主功能的顶部,然后在需要引用所有者
Bidule
时,在所有子模块中引用该
。其次,没有
random()
方法,所以不能只做
=random()
,所以你的
fn.random.set
fn.random.add
不起作用,你为什么希望你的方法那样嵌套?由于
这个问题,它不是一个典型的JavaScript习惯用法。为什么不把它们直接放到
Bidule.prototype
?然后你就可以做
b.plus(4)
@Lan:我知道
random()
不存在,只是举个简单的例子。嗯。。。我知道在变量中设置
this
会起作用,但原型无法访问私有变量
this
@疯狂火车:我知道这并不典型,但我发现这个问题和实现这个问题的方法都很有趣。我想知道其他人的答案和观点。是的,当然,这会奏效。但是,构造函数不使用原型:
var Bidule=function(){var self=this;…};Bidule.prototype={}。在这里,原型将无法访问
var self
。我们可以这样放置原型:
var Bidule=function(){var self=this;this.prototype={…};}
但这意味着每次调用构造函数时都会设置原型,所以这也不是一个好方法。我能想到的唯一方法是使fn成为一个返回对象的函数。看我的JSFIDLE是的,的确,这是一个很好的方法。然而,我们必须改进它,就像在您的示例中一样,
fn()
将在每次调用它时构建这些方法。但也许有一种方法可以将“fn”中的集群方法导出到外部,并只返回一个引用。