OO Javascript 构造函数模式:新古典与原型 [英] OO Javascript constructor pattern: neo-classical vs prototypal

查看:33
本文介绍了OO Javascript 构造函数模式:新古典与原型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我观看了道格拉斯的演讲Crockford 谈 Javascript 的优点 和我的眼睛被打开.有一次他说,Javascript 是唯一一种优秀的程序员相信他们可以有效地使用它而无需学习它的语言."然后我意识到,我就是那个人.

I watched a talk by Douglas Crockford on the good parts in Javascript and my eyes were opened. At one point he said, something like, "Javascript is the only language where good programmers believe they can use it effectively, without learning it." Then I realized, I am that guy.

在那次演讲中,他做了一些对我来说非常令人惊讶和有见地的陈述.例如,JavaScript 是地球上最重要的编程语言.或者它是这个星球上最流行的语言.而且,它在许多严重的方面都被打破了.

In that talk, he made some statements that for me, were pretty surprising and insightful. For example, JavaScript is the most important programming language on the planet. Or it is the most popular language on the planet. And, that it is broken in many serious ways.

对我来说,他发表的最令人惊讶的声明是新事物很危险".他不再使用它了.他也不使用this.

The most surprising statement he made, for me, was "new is dangerous". He doesn't use it any more. He doesn't use this either.

他为 Javascript 中的构造函数提供了一种有趣的模式,该模式允许私有和公共成员变量,并且既不依赖于 new,也不依赖于 this.它看起来像这样:

He presented an interesting pattern for a constructor in Javascript, one that allows for private and public member variables, and relies on neither new, nor this. It looks like this:

// neo-classical constructor
var container =  function(initialParam) {
    var instance = {}; // empty object 

    // private members
    var privateField_Value = 0;
    var privateField_Name = "default";

    var privateMethod_M1 = function (a,b,c) {
        // arbitrary
    }; 

    // initialParam is optional
    if (typeof initialParam !== "undefined") {
        privateField_Name= initialParam;
    }

    // public members
    instance.publicMethod = function(a, b, c) {
        // because of closures,
        // can call private methods or
        // access private fields here. 
    };

    instance.setValue = function(v) {
        privateField_Value = v;
    };

    instance.toString = function(){
        return "container(v='" + privateField_Value + "', n='" + privateField_Name + "')";
    };

    return instance;
}


// usage
var a = container("Wallaby");
WScript.echo(a.toString()); 
a.setValue(42);
WScript.echo(a.toString()); 

var b = container();
WScript.echo(b.toString()); 

EDIT:代码更新以切换到小写类名.

EDIT: code updated to switch to lowercase class name.

这种模式是从 Crockford 早期的使用模型演变而来的.

This pattern has evolved from Crockford's earlier usage models.

问题:你使用这种构造器模式吗?你觉得可以理解吗?你有更好的吗?

Question: Do you use this kind of constructor pattern? Do you find it understandable? Do you have a better one?

推荐答案

这看起来像 模块模式,利用JavaScript的闭包"可以模拟私有变量.

This looks like the non-singleton version of the module pattern, whereby private variables can be simulated by taking advantage of JavaScript's "closures".

我喜欢它(有点......).但是我并没有真正看到以这种方式完成私有变量的优势,尤其是当这意味着添加的任何新方法(在初始化之后)都无法访问私有变量时.

I like it (kinda...). But I don't really see the advantage in private variables done in this way, especially when it means that any new methods added (after initialisation) do not have access to the private variables.

另外,它没有利用 JavaScript 的原型模型.每次调用构造函数时都必须初始化所有方法和属性 - 如果您将方法存储在构造函数的原型中,则不会发生这种情况.事实是,使用传统的构造函数/原型模式要快得多!您真的认为私有变量使性能受到影响值得吗?

Plus, it doesn't take advantage of JavaScript's prototypal model. All your methods and properties must be initialised EVERY time the constructor is called - this doesn't happen if you have methods stored in the constructor's prototype. The fact is, using the conventional constructor/prototype pattern is much faster! Do you really think private variables make the performance hit worth it?

这种模型对模块模式有意义,因为它只被初始化一次(以创建一个伪单例),但我不太确定它在这里是否有意义.

This kind of model makes sense with the module pattern because it's only being initialised once (to create a pseudo-singleton), but I'm not so sure it makes sense here.

你使用这种构造器模式吗?

Do you use this kind of constructor pattern?

不,虽然我确实使用了它的单例变体,但模块模式...

No, although I do use its singleton variant, the module pattern...

你觉得它可以理解吗?

是的,它具有可读性且非常清晰,但我不喜欢将所有内容都集中在像这样的构造函数中的想法.

Yes, it's readable and quite clear, but I don't like the idea of lumping everything inside a constructor like that.

你有更好的吗?

如果你真的需要私有变量,那么一定要坚持使用它.否则,只需使用传统的构造函数/原型模式(除非你和 Crockford 一样害怕 new/this 组合):

If you really need private variables, then stick with it by all means. Otherwise just use the conventional constructor/prototype pattern (unless you share Crockford's fear of the new/this combo):

function Constructor(foo) {
    this.foo = foo;
    // ...
}

Constructor.prototype.method = function() { };

与道格对该主题的看法相关的其他类似问题:

Other similar questions relating to Doug's views on the topic:

这篇关于OO Javascript 构造函数模式:新古典与原型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆