JavaScript函数封装在对象外部

时间:2009-10-05 08:09:52

标签: javascript oop prototype object encapsulation

请参阅以下脚本:

var x = function(param){
    this.data=param;

    this.y = function(){
        alert(this.data)
    }

    return this;
}

/*
    x.prototype.z = function(){
        alert(this.data);
    }
*/

x(123).y();
x(123).z(); // This should behave same as y()

当我致电 x(123).y() 时,消息会显示 123 。在 x()

中声明的功能 y()

现在我要宣布另一个功能 z() ,它将位于 x() 之外,但是行为与 y() [与 x() 相关联]

有可能吗?如果可能的话怎么办?

3 个答案:

答案 0 :(得分:3)

致电new时,您错过了x()。否则,函数体中的this将引用全局对象(浏览器上下文中为window),而不是x的实例。

这就是为什么调用z()(在取消注释代码之后)不起作用的原因。调用y()仅在创建全局变量data时巧合,其值将在下一次调用x()时被覆盖。


我不知道你想要完成什么,从我所看到的,它很可能不是一个好主意。无论如何,这是一个在创建对象时如何摆脱显式new的例子:

var x = function(param){
    // add missing `new`:
    if(!(this instanceof x))
        return new x(param);

    this.data=param;

    this.y = function(){
        alert(this.data)
    }
}


x.prototype.z = function(){
    alert(this.data);
}

x(123).y();
x(456).z();

答案 1 :(得分:1)

如果您确定了创建z的方式,那么您的注释掉的x函数应该可以正常工作。

请注意,如果函数y仅处理实例属性(在代码中属性),则不必在构造函数内声明它,并且这样做会产生大量内存成本(每个实例都会获得) 该函数的自己的副本)。考虑到所涉及的成本,如果出于重大数据隐藏原因,您只需要这样做。

编辑:抱歉,我错过了一些内容:您错过了new关键字,您的示例应为:

new x(123).y();
new x(123).z();

...并且您的构造函数不应返回this

完整示例:

var x = function(param) {

    this.data=param;

    // Doesn't have to be in the constructor, and you should
    // avoid it unless you're doing something with major
    // data hiding a'la Crockford
    this.y = function() {
        alert(this.data)
    }
}

x.prototype.z = function() {
    alert(this.data);
}

new x(123).y();
new x(123).z();

This is the Crockford article我在上面提到过,但同样,它有很大的记忆意义。

答案 2 :(得分:0)

function generator( param ) {
    this.data = param;
    this.y = function() {
        alert( this.data )
    }
}

generator.prototype.z = function() {
    alert( this.data );
}

x = new generator( 3 );
x.y()
x.z()

不确定这是否是您想要的,但这是一个名为generator的构造函数,它返回一个对象,并使用new关键字在其外部定义原型方法。

正如其他人所说:

  • 您无需在构造函数
  • 中返回this
  • 您使用new关键字
  • 进行调用
  • 使用this声明的所有方法都是公开的,除非您使用var,在这种情况下,它们会变为私有