JavaScript函数封装在对象之外

发布于 2024-08-07 03:59:05 字数 663 浏览 6 评论 0原文

请参阅以下脚本:

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()关联]

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

Please see the following script:

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()

When I call x(123).y() then message displays 123. The function y() declared inside x()

Now I want to declare another function z() which will reside outside x() but will behave same as y() [associate with x()]

Is it possible? If possible how?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

自控 2024-08-14 03:59:06

调用 x() 时缺少 new。否则,函数体内的 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();

You're missing a new when calling x(). Otherwise, this within the function body will refer to the global object (window in browser contexts) and not an instance of x.

That's the reason why calling z() (after un-commenting the code) doesn't work. Calling y() only works by coincidence as you create a global variable data, whose value will be overwritten by the next call to x().


I have no idea what you're trying to accomplish, and from what I can see, it most likely isn't a good idea. Anyway, here's an example of how to get rid of explicit new when creating objects:

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();
勿忘初心 2024-08-14 03:59:06

这是可能的,如果您修复了创建 x 的方式,则注释掉的 z 函数应该按原样工作。

请注意,如果您的函数 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();

这是我上面提到的 Crockford 文章,但同样,它对内存有很大的影响。

It is possible, and your commented-out z function should work as is if you fix how you're creating xs.

Note that your function y doesn't have to be declared inside the constructor if it's only dealing with instance properties (which in your code it is), and doing so has a significant memory cost (every instance gets its own copy of that function). You only want to do that if you absolutely have to for major data hiding reasons, given the costs involved.

Edit: Sorry, I missed something: You're missing the new keyword, your examples should be:

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

...and your constructor shouldn't return this.

Complete example:

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 I mention above, but again, it has big memory implications.

骑趴 2024-08-14 03:59:06
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 在这种情况下它们变成私有的
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()

Not sure if this is what you want, but this is a constructor named generator which returns an object, and a prototypal method is defined outside of it with the new keyword.

As others stated:

  • you don't need to return this in the constructor
  • you call it with the new keyword
  • all methods declared with this are public unless you use var in which case they become private
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文