javascript类定义之间有什么区别?

javascript类定义之间有什么区别?,javascript,jquery,Javascript,Jquery,正如您所知,JavaScript在语法方面是一种非常灵活的面向对象语言,但我的问题是,JavaScript中定义函数的哪种方式比较流行 是否只有javascript提供了多向帮助,以了解其他人的代码,或者多向是基于性能原因 1。使用函数 function Apple (type) { this.type = type; this.color = "red"; this.getInfo = getAppleInfo; function getAppleInfo()

正如您所知,JavaScript在语法方面是一种非常灵活的面向对象语言,但我的问题是,JavaScript中定义函数的哪种方式比较流行

是否只有javascript提供了多向帮助,以了解其他人的代码,或者多向是基于性能原因

1。使用函数

function Apple (type) {
    this.type = type;
    this.color = "red";
    this.getInfo = getAppleInfo;
    function getAppleInfo() {
        return this.color + ' ' + this.type + ' apple';
    }
}
var apple = new function() {
    this.type = "macintosh";
    this.color = "red";
    this.getInfo = function () {
        return this.color + ' ' + this.type + ' apple';
    };
}
2。使用对象文字

var apple = {
    type: "macintosh",
    color: "red",
    getInfo: function () {
        return this.color + ' ' + this.type + ' apple';
    }
}
3。使用函数的单例

function Apple (type) {
    this.type = type;
    this.color = "red";
    this.getInfo = getAppleInfo;
    function getAppleInfo() {
        return this.color + ' ' + this.type + ' apple';
    }
}
var apple = new function() {
    this.type = "macintosh";
    this.color = "red";
    this.getInfo = function () {
        return this.color + ' ' + this.type + ' apple';
    };
}
  • 使用函数vs
  • 使用对象文字
  • 意味着您需要调用它来获取实例:

    var apple = new Apple("Macintosh");
    
    然后,它相当于使用对象文字创建的对象。但是,使用构造函数可以优化多个实例之间的共享值,主要是以下方法:

    function getInfo() {
        return this.color + ' ' + this.type + ' apple';
    }
    function Apple (type) {
        this.type = type;
        this.color = "red";
        this.getInfo = getAppleInfo;
    }
    var apple1 = new Apple("Macintosh"),
        apple2 = new Apple("Golden Delicious");
    apple1.getInfo === apple2.getInfo // only one function object!
    
    然而,工厂函数也可以通过返回对象文字来实现这一点。将
    new
    与构造函数一起使用还有一个额外的优点,即实例共享其原型对象,从中继承属性。我们可以简化为

    function Apple (type) {
        this.type = type;
        this.color = "red";
    }
    Apple.prototype.getInfo = function getInfo() {
        return this.color + ' ' + this.type + ' apple';
    };
    // now, having
    var apple2 = new Apple("Golden Delicious");
    apple2.getInfo === Apple.prototype.getInfo // still only one function object
    apple2.getInfo() // and we can access it directly on instances without explicitly
                     // having created a property on them!
    apple2 instanceof Apple // is also a feature
    
    有关更多详细信息,请参阅

    3使用函数的单例

    var apple = new function() {
    

    。它掩盖了构造函数的存在,该构造函数允许您在背后构造其他非单例实例。

    您的选项1和3基本相同。要创建实例,需要使用
    new
    调用选项1。选项3只是马上做。但这有点奇怪,因为如果只有一个对象,那么最好使用选项2(对象文字)

    您缺少了另一个常用选项,我想您可以称之为对象工厂。在这种情况下,基本上将选项2包装在一个函数中,以便能够实例化对象的多个副本

    您还缺少对函数原型的任何使用,这在使用方法实例化类时非常重要,因为性能原因。例如:

    var Apple = function () {
        this.type = "macintosh";
        this.color = "red";
    };
    Apple.prototype = {
        getInfo: function () {
            return this.color + ' ' + this.type + ' apple';
        }
    };
    
    var myApple = new Apple();
    
    在本例中,只存在
    getInfo
    方法的一个副本,而在您的示例中,每次实例化苹果时都会重新创建该方法。此外,使用原型还可以利用原型继承。有点令人困惑的是,新版本的Javascript中引入了一些方法来实现这一点,但它们最终都是一样的

    如果我需要一个没有任何方法的对象,或者如果我使用以前定义的函数作为方法(例如,不在每次实例化对象时创建新的函数表达式),我将使用您的选项2。否则,我将使用原型和构造函数


    我建议阅读Reg Braithwaite的Javascript Allongé,这确实让我感受到了如何充分利用Javascript函数和对象模型。

    首先,我必须告诉你,我不是专家,你可能会在这个问题上找到更好(完整)的答案

    原型 这三种方法的最大区别在于原型。方法1
    [Usin a function]
    将允许您绑定其他对象之间未共享的原型对象

    您可以将原型方法添加到
    Apple
    对象以及
    object
    对象中。例如,见:

    //init
    Object.prototype.hello = 'Hello';
    Apple.prototype.world = ' World';
    
    //Method 1
    alert(apple.hello + apple.world); //Hello World
    
    //Method 2
    alert(apple.hello + apple.world); //Helloundefined
    
    //Method 3
    alert(apple.hello + apple.world); //Helloundefined
    
    可重复利用性 如果您想要同一对象的多个实例,那么如果没有第一个方法,您的日子会很不好过。如您的示例所示,如果您想要两个不同的苹果,则需要复制/粘贴并更改属性(第一种方法除外)

    可变范围 在方法1和方法3中,可以使用局部变量。对象外部无法访问的元素

    当对象中有事件处理函数时,这有点有用。在这些函数中,您将丢失
    引用。幸运的是,您可以将其保存在局部变量中。以
    timeout
    为例,不要用
    .bind()之类的东西作弊:

    识别 我能想到的最后一件事就是身份证明。基本上,使用方法#1,您可以很容易地知道对象是一个苹果:

    //Method 1
    alert(apple instanceof Object); //True
    alert(apple instanceof Apple); //True
    
    //Method 2
    alert(apple instanceof Object); //True
    alert(apple instanceof Apple); //False
    
    //Method 2
    alert(apple instanceof Object); //True
    alert(apple instanceof Apple); //False
    
    肯定还有其他好处 如果有人能在这些问题上找到其他优势,我将不胜感激:

    • 记忆
    • 演出
    • 可读性
    • 编程语言兼容性(例如:通过JSON将对象转换为PHP)
    • 其他我想不起来的事情

    遗言 我从未使用过,也永远不会使用singleton函数来创建对象。我在某个地方读到过(现在找不到参考资料)使用
    新函数是一种不好的做法,对性能影响很大。请注意,我在这里可能是错的…

    简单地回答您的问题“哪种方法比较流行?”我必须说,我在野外见过各种不同的方法在各种组合中使用。没有标准的方法(结果是有很多错误)

    之所以有多种方法,是因为JS不是一种面向对象的语言。它是一种基于对象的脚本语言,最初并不打算用于大规模应用程序和库。由于灵活的语法,它允许您在5行代码中完成一些看起来非常壮观的事情,但是当需要大规模的健壮性和可读性时,它就变成了一场噩梦

    我亲自编写了一个JavaScript库,它试图在C++中像JS那样带来一个干净自然的语法,首先声明,定义之后,并且允许在JS.

    中使用静态、私有、保护、虚拟等成员。 。这是语法的一个基本示例:

    ;( function class_Template( namespace )
    {
        'use strict'; // recommended
    
        if( namespace[ "Template" ] ) return    // protect against double inclusions
    
            namespace.Template = Template
        var Static             = TidBits.OoJs.setupClass( namespace, "Template", "BaseClass" )
    
        // Static data members, private by default
        //
        Static.privateStaticDM   = 0
        Static.protectedStaticDM = 0
        Static.publicStaticDM    = 0
    
        Static.Private
        (
              "privateStaticDM"     //< can do for consistency, but private is the default
            ,  privateStaticMethod  //  accesslevel for data members
        )
    
        Static.Protected
        (
              "protectedStaticDM"
            ,  protectedStaticMethod
        )
    
        Static.Public
        (
              "publicStaticDM"
            ,  publicStaticMethod
        )
    
        // constructor
        //
        function Template( parameter )
        {
            // Data members
            //
            this.privateInstanceDM   = parameter
            this.protectedInstanceDM = 0
            this.publicInstanceDM    = 0
    
            this.Private
            (
                  "privateInstanceDM"
                ,  init
    
                ,  this.Virtual
                   (
                        virtualPrivateInstanceMethod
                   )
            )
    
            this.Protected
            (
                  "protectedInstanceDM"
                ,  protectedInstanceMethod
            )
    
            var iFace = this.Public
            (
                  "publicInstanceDM"
                ,  publicInstanceMethod
            )
    
            this.init() // if you have to do something else
    
            return iFace
        }
    
        // all your method definitions go here
        //
        function init(){}
        function privateStaticMethod(){}
    
    })( window )
    
    ;(函数类\模板(命名空间)
    {
    “使用严格”;//推荐
    if(namespace[“Template”])返回//防止双重包含
    namespace.Template=Template
    var Static=TidBits.OoJs.setupClass(名称空间,“模板”,“基类”)
    //静态数据存储器