Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/397.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不同的OOP方法标准_Javascript_Class_Oop_Methods - Fatal编程技术网

javascript不同的OOP方法标准

javascript不同的OOP方法标准,javascript,class,oop,methods,Javascript,Class,Oop,Methods,在最长的一段时间里,我一直在通过以下方式来完成JavaScript类 function MyClass(){ this.v1; this.foo = function(){ return true; } }; 然后我找到了TypeScript,它看起来像是把它的类编译成 var MyClass = (function () { function MyClass(message) { this.v1 = message; }

在最长的一段时间里,我一直在通过以下方式来完成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;
    }
};
这在我看来很难看,但也许我错过了这种方法的一些有益之处,因为它看起来是大多数web用户使用javaScript处理对象的方式

我能做的第一个方法是从我做的一个函数中获得内在性

Function.prototype.extends = function(parent){
    this.prototype = new parent();
    this.prototype.constructor = this;
};
我还看到了许多其他用JavaScript创建类的方法。我想知道我的方法是否错误,或者在OOP中是否有最佳实践方法。我做的所有项目都使用第一个示例。你们可以看到,现在我看到JavaScript编译器在做什么,我开始质疑我的方法。我想知道其他JavaScript程序员建议的最佳方法是什么,以及这些方法之间是否存在差异。我来自C++/Java背景,因此我编写JavaScript以匹配我的背景

这里解释了这一点

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


您在此处阅读的内容称为幂构造函数,更多信息请参见:


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

换句话说,如果你能用一种方式来解释你的结构,那就不要用那种方式

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

我经常做的是:

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)
}
编辑:只有在需要分解p0时才需要内部闭包(即在每次调用时为p0提供单独、独立的值)。当然,如果不需要p0分解,请忽略内部闭包

上面的例子故意比说明各种有趣案例所需的复杂

像调用
myItemBuilder(“hello”)
这样调用此方法将构建一个具有这些特定功能的新项,但实际上没有
class
构造本身

当您想要放弃经典继承时,这是一种获取实例的特别强大的方法。例如,C++中可以从多个类继承,这被称为混合。在Java和C#中,您只有一个继承,但接口可以帮助您

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

如果你真的理解,所有这些都是有意义的。否则,我请你原谅我这么长的回答:)

添加:


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

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

var MyClass = {
    v1:1,
    foo: function(){
       return true;
    }
};
结果是更少的字符和更小的JS文件,所以这是我通常使用的方法,但没有错误或正确的方法。顺便说一句,既然你评论这种对象结构很难看,你可能想坚持你习惯的。然而,如果你有冒险的感觉


它使javascript中的oop快速、轻松,并且不那么难看。另外,它还正确地支持多重继承。

在js中有一百万种不同的“OOP”方式;所有这些都有一些小的优点和缺点,但很少会因为这些差异而导致“对”或“错”。您的代码可能更像Brendan所想的,而不是typescript的版本。两者可能都有重复,但使用
prototype
更为标准。在第一个示例中,您无法实现继承或多态性。例如,new(MyClass)创建的所有对象都是从object继承而来的,其他什么都没有。使用this.foo()和this.prototype.foo()来考虑这样的对象会有所不同吗。我将回顾这篇文章,看看我是否完全掌握了它。这很像java工厂吗?具体工厂和抽象工厂是创造性的GoF模式。我想java工厂就是这两个工厂之一的实现。装配线隐喻非常相似,但它不仅仅是一种模式,它是原型继承范式的一部分。如果所有这些都没有意义,不要害怕,只需按照您所知道的方式使用JS,因为最重要的是您理解并能够维护自己的代码。若你们不知道自己在做什么,并没有人知道:)怎么回事}(p1));在函数的末尾做什么?函数在开头有(p1)。但我不知道最后一个在做什么,它调用刚刚定义的函数。真正的名字是它非常像java的foo(x=3){/*doSMTHG*/}这是一个正确的假设吗?