8

定义类的最佳方法是什么?我知道大多数时候这是您喜欢使用的选择,但是这三个示例之间的直接区别是什么?

示例 1

var Class = (function(){
    function Class() {
      this.test = 'test'                
    }
    return Class;
})();

var c = new Class();
console.log(typeof Class);
console.log(c.test);

示例 2

var Class2 = function(){
      this.test = 'test'                
};

var c2 = new Class2();
console.log(typeof Class2);
console.log(c2.test);

示例 3

function Class3(){
      this.test = 'test'                
};

var c3 = new Class3();
console.log(typeof Class3);
console.log(c3.test);

有时我也这样使用它: var Class = (function(){ var Private = {}, Public = {};

    Private._doSomething = function() {
        // something
    }

    Public.doSomethingElse = function() {
        // something else
    }
    return Public;
    })();
4

1 回答 1

7

注意:下面的主要答案是在 2012 年编写的。有关 JavaScript 自身class功能(ES2015+)的附加说明,请参见末尾。


“最佳”本质上是一个主观的东西,但我会尝试指出一些有关每个信息的信息,让您对“最佳”做出自己的判断。

示例 1

Class...为您提供了一个方便的范围(匿名函数),您可以在其中放置只有函数可以访问的真正私有的类范围信息(和实用函数) :

var Class = (function(){
    var trulyPrivateInformation = 42;

    function trulyPrivateUtilityFunction() {
        // ...
    }

    function Class() {
      this.test = 'test';
    }
    return Class;
})();

示例 1 未“提升”。它作为分步代码的一部分进行处理。

Class函数将具有真实名称。

示例 2

...创建一个没有名称的函数并将其分配给一个有名称的变量。现代浏览器对此非常聪明,但至少在理论上,该功能是匿名的,这会影响您的工具可以为您提供哪些信息。(从 ES2015 开始)有一个名称 ( Class2),但在 IE 等过时的环境中除外。它没有示例 1 具有的私有类范围。

与示例 1 一样,示例 2 作为分步代码的一部分进行处理,而不是提升。

示例 3

...只是没有私有类范围范围的示例 1,但它也是“提升的”——该Class函数是在执行任何分步代码之前定义的。这意味着这有效:

var c = new Class();
console.log(c.test); // Logs 'test'

function Class() {
    this.test = 'test';
}

请注意,即使Class定义较低,它也是在上面的代码运行之前完成的。示例 1 或示例 2 都不是这样。

与示例 1(但不是 2)一样,该Class函数具有真实名称。


2015 年,JavaScript 有了自己的class语法。在 2019 年,所有现代浏览器都原生支持它,如果需要支持 IE,可以使用 Babel 等工具进行转译。以下是class与 OP 问题的关系:

示例 1class

const Class = (() => {
    let trulyPrivateInformation = 42;

    function trulyPrivateUtilityFunction() {
        // ...
    }

    return class Class {
        constructor() {
            this.test = 'test';
        }
    }
})();

在代码的逐步执行中处理。对真正私有的东西具有真正的私有范围(在匿名范围函数内)。有正确的名字。

示例 2 与class(这也是示例 3 与class

class Class2 {
    constructor() {
        this.test = 'test';
    }
}

let c2 = new Class2();
console.log(typeof Class2);
console.log(c2.test);

在代码的逐步执行中处理。没有示例 1 所具有的真正私有范围(尽管私有字段和方法即将推出)。有正确的名字。

于 2012-12-05T14:12:36.663 回答