【问题标题】:Using this or new in JS?在 JS 中使用 this 还是 new ?
【发布时间】:2015-12-19 20:21:32
【问题描述】:

我有 3 个代码:

var control = new Control();

function Control() {

   this.doSomethingElse = function() {...}
   this.doSomething = function () {
       control.doSomethingElse();
   }

}

或者

var control = new Control();

function Control() {
   var self = this;

   this.doSomethingElse = function() {...}
   this.doSomething = function () {
       self.doSomethingElse();
   }
}

或者

var control = Control();

function Control() {
   var self = this;

   this.doSomethingElse = function() {...}
   this.doSomething = function () {
       self.doSomethingElse();
   }

  return self;
}

重要:该函数是一个控制器,并且只声明了一次。然后我在我的代码中到处使用“控制”......

我想知道 control.doSomethingElse() 是否很慢?

最后,在这些示例中,什么是正确的做法和/或最快的代码?

谢谢!

【问题讨论】:

  • #1 是错误的 - 对象永远不应该在内部使用外部已知的名称。这就是this(或self)的用途。
  • @Alnitak:他正在使用单例对象。看起来他根本不需要构造函数。
  • @squint true,但在这种情况下,他不应该在作业中使用this - 只需function Control() { return { doSomethingElse: ..., doSomething: ... } }

标签: javascript this declare


【解决方案1】:

第一个是错误的——一个对象不应该在内部使用它在外部已知的变量名。其他代码可能会将该变量更改为指向其他内容,从而破坏此代码。

第三个也是错误的——当在没有new的情况下调用Control()时,内部对this.foo的赋值最终会附加到全局对象上(除了在严格模式下,在裸函数上没有隐式this调用,因此对this.doSomethingElse 的赋值尝试附加到undefined,导致运行时错误。

只留下适当的第二个,但最终这是一个正确性问题,而不是性能问题。

【讨论】:

    【解决方案2】:

    不要在构造函数中定义方法 - 这意味着每次创建实例时都定义它们。请改用Control.prototype.foo = function() {}。此外,如果您使用 new 运算符,则不需要 return this - 这就是 new 运算符的全部意义。

    推荐的方法是这样的:

    function MyClass(param1) {
        // Here we're changing the specific instance of an object
        this.property1 = param1;
    }
    // Prototype will be shared with all instances of the object
    // any modifications to prototype WILL be shared by all instances
    MyClass.prototype.printProperty1 = function() {
        console.log(this.property1);
    }
    
    var instance = new MyClass("Hello world!");
    instance.printProperty1(); // Prints hello world
    

    要理解这段代码,你需要理解 javascript 的基于原型的继承模型。当您创建 MyClass 的实例时,您将获得一个新对象,该对象继承了 MyClass.prototype 中存在的任何属性。 Read more about it.


    我也想知道:

    该函数是一个控制器,并且只声明了一次。

    如果您不多次使用它,则不需要创建类之类的东西。你可以这样做:

    var control = {doSomething:function() { ... }};
    

    我假设您已经习惯了 Java,其中一切都必须是一个类,无论它是否有意义。 Javascript不同,你也可以根据需要制作单个对象或函数。

    【讨论】:

    • 在构造函数中定义方法有很多非常好的理由,单例就是其中之一,因为重复创建相同函数的多个副本没有任何开销。对它教条主义弊大于利。
    • @Alnitak 我提到了如何在 Javascript 中定义单例。而且我不是教条主义 - 我提到了我不鼓励 OP 的方法的原因,这取决于他做出决定。
    • 大家好,谢谢大家的回答,是的,我天生就是java,喜欢干净的代码,但是,性能呢?哪个答案的执行/访问速度最快?
    • @alexino2 正如 Alnitak 指出的那样,如果您只创建一个实例,那没关系。但一般来说,在制作Javascript伪类时,不要在构造函数中定义方法。我的回答中描述了原因。
    • @Tomáš Zato 是的,它是一个单例 :) 最后的重点是要知道“self = this”是否像原型一样,还是“this”的新副本?或者如果使用“控制”更快?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-15
    • 2013-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-25
    • 1970-01-01
    相关资源
    最近更新 更多