javascript不同的OOP方法标准

javascript different OOP methods standards

本文关键字:方法 标准 OOP javascript      更新时间:2023-09-26

很长一段时间我一直在做JavaScript类做以下

function MyClass(){
    this.v1;
    this.foo = function(){
        return true;
    }
};

然后我找到TypeScript,看起来它把它的类编译成

var MyClass = (function () {
    function MyClass(message) {
        this.v1 = message;
    }
    MyClass.prototype.foo = function () {
        return "Hello, " + this.v1;
    };
    return MyClass;
})();

我在网上发现的另一个方法是

var MyClass = {
    v1:1,
    foo: function(){
       return true;
    }
};

这对我来说看起来很丑,但也许我错过了这个方法的一些有益的东西,因为它看起来是大多数人在javaScript中做对象的方式。

我能够从我创建的函数继承的第一个方法。

Function.prototype.extends = function(parent){
    this.prototype = new parent();
    this.prototype.constructor = this;
};

我也见过很多在JavaScript中创建类的方法。我想知道如果我的方法是错误的,或者如果有做面向对象的最佳实践方法。我所做的所有项目都使用第一个例子。你可以在https://github.com/Patrick-W-McMahon上看到,现在我看到JavaScript编译器在做什么,我开始质疑我的方法。我想知道其他JavaScript程序员建议什么是最好的方法,如果有方法之间的差异。我有c++/Java背景,因此我编写的JavaScript与我的背景相匹配。

你在这里读到的被称为power构造函数,更多信息在这里:

Douglas Crockford谈遗产


作为一种多范式语言,JavaScript非常适合这些不同的考虑。事实是,它以你所能想象的方式塑造了你的大脑。

换句话说,如果你能用一种方式来推断你的结构,那就用这种方式。

另一方面,如果您希望完全"自由"于您自己的约束,那么您应该完全放弃类中的推理,并接受原型继承,而不需要任何类似于类的东西。鸭子类型是一个自然的结果,在极端情况下,你会到处使用闭包。

我经常这样做:

function myItemBuilder(p1)
{
  var s0, p0 = 0;
  // s0 is a shared private property (much like static in classes)
  // p0 is a shared private property but will be factorized (rendered non-shared)
  // p1 is a private instance property
  return (function (p0) { // factorize p0 if necessary
    return {
      publicProperty : 3,
      method1 : function (arg1) {
        // code here (may use publicProperty, arg1, s0, p0 (factorized) and p1)
      },
      method2 : function (arg2) {
        // code here (may use publicProperty, arg2, s0, p0 (factorized) and p1)
      }
    };
  }(p0++)); // on each invocation p0 will be different and method1/method2 will not interfere across invocations (while s0 is shared across invocations)
}

EDIT:内部闭包仅在需要分解p0时才需要(即在每次调用时为p0设置单独的独立值)。当然,如果不需要分解p0,可以省略内部闭包。

上面的例子故意比需要的更复杂,以说明各种有趣的情况。

myItemBuilder("hello")那样调用这个方法构建了一个具有这些特定功能的新项目,但实际上没有class构造本身

当你想放弃经典继承时,这是获取实例的一种特别强大的方式。例如,在c++中,您可以从多个类继承,这称为mix-in。在Java和c#中,你只有单继承,但是接口可以帮助你。

在这里,我上面展示的是装配线隐喻,它可以将组件组装到一个实例中,结果是在类、接口和混合之间没有具体的(1)区别。它们都只是具有特性的实例,可以通过元编程(duck typing,反射/检查)进行反映。逻辑(2)区别在于:(1)具体实例的行为与它们产生的方式无关,但(2)逻辑上接口是契约,而实例是实现。

如果你真正理解SOLID和装配线比喻,所有这些都是有意义的。否则,请原谅我这么长时间的回答:)

补充道:

使用这种方法,您不能检查类型,但您不需要检查类型,因为duck类型允许您找到所需的方法,而无需查看类或接口契约。这类似于将每个方法放在单独的单方法接口中。

此处说明

http://www.2ality.com/2011/06/coffeescript-classes.html

一个普通的JavaScript类定义,封装在IIFE[3]中。在这里使用IIFE没有任何好处,除了有一个单一的赋值(这在对象字面量中很重要,但在这里没有)。

这是个人喜好的问题。使用这个方法

var MyClass = {
    v1:1,
    foo: function(){
       return true;
    }
};

导致更少的字符,因此更小的JS文件,所以这是我通常使用的方法,但没有错误或正确的方式。顺便说一句。既然您评论过这种类型的对象构造是丑陋的,那么您可能想要坚持使用您所习惯的。然而,如果你觉得冒险,看看这个项目。

它使javascript中的oop快速,无痛且不难看。此外,它还正确支持多重继承。