简体   繁体   English

“ new”如何与javascript中的类一起使用?

[英]how does “new” work with classes in javascript?

How does the new work differently in the 2 examples below? 以下两个示例中的new有何不同? I see that the 2nd example is replacing the annoymous funciton with a variable, but in the second one, the function/class "Person" is actually being called. 我看到第二个示例用一个变量替换了异常函数,但是在第二个示例中,实际上正在调用函数/类“ Person”。 Does it make any difference if it's being called or not? 是否被调用会有所不同吗? I tried it without the calling and it still worked. 我没有打电话就尝试了,它仍然有效。 So that led me to believe that new is actually calling the function and setting up this to be assigned to the instance variable. 所以这使我相信,新的实际上是调用函数和设置this被分配到的实例变量。

  var person = new function() { this.setName = function(name) { this.name = name; } this.sayHi = function() { return "Hi, my name is " + this.name; } } person.setName("Rafael"); console.log(person.sayHi()); // Hi, my name is Rafael 

  var Person = function() { this.setName = function(name) { this.name = name; } this.sayHi = function() { return "Hi, my name is " + this.name; } } var personTwo = new Person() personTwo.setName("Rafael"); console.log(personTwo.sayHi()); // Hi, my name is Rafael 

There would be almost no difference between these two examples, if it was a simple function like this: 如果这是一个简单的函数,那么这两个示例之间几乎没有区别:

 (function() { console.log("IIFE"); })(); // or var f = function() { console.log("Function"); }; f(); 

You just store your function in a variable, and then call it. 您只需将函数存储在变量中,然后调用它。

However, it makes a little difference, since it is related to JS OOP mechanisms. 但是,由于它与JS OOP机制相关,因此它并没有什么区别。 In the first case you get Object instance, and in the second you get Person instance. 在第一种情况下,您获得Object实例,在第二种情况下,您获得Person实例。 This makes difference in OOP sense. 这使OOP意义有所不同。

 var person = new function() { }; console.log("Is instance of: " + person.constructor.name); console.log("There is no way to check instanceof in this case"); var Person = function() { }; var person = new Person(); console.log("Is instance of: " + person.constructor.name); console.log(person instanceof Person); 

In general, new and classes are supposed to be used as in the second case in order to enable the full functionality of JS OOP. 通常,应该在第二种情况下使用new和class,以启用JS OOP的全部功能。 There is absolutely no sense or/and advantage in using anonymous class constructor. 使用匿名类构造函数绝对没有任何意义或优势。

Whether or not it is assigned into a variable: does not matter. 是否将其分配给变量:无关紧要。 It is completely parallel to this example: 它与本示例完全平行:

var x = 1;
console.log(x);

and

console.log(1);

Whether it needs to be called or not: A function with the new operator is always being called, but with new , parentheses are optional when no parameters are passed: new Person() is equivalent to new Person , but new Person("Joe") cannot be done differently. 是否需要调用:始终调用带有new运算符的函数,但是带有new的函数,当不传递任何参数时,括号是可选的: new Person()等同于new Person ,但是new Person("Joe")不能做不同的事情。

In the second example, you are passing to the new operator the exact same function. 在第二个示例中,您将完全相同的函数传递给运算符。 You simply are using a reference (logically stored in a variable) instead of writing literal function just in place. 您只是使用引用(逻辑上存储在变量中),而不是就地编写文字函数。

So, your second example is the same as: 因此,您的第二个示例与以下示例相同

var personTwo = new (function() {  
    [...]
})()
[...]

Which, in fact, is much the same as the first one: 实际上,这与第一个基本相同:

var person = new (function() {  
    [...]
})
[...]

NOTE that the parentheses surrounding the function are absolutely optional in this case. 注意 ,在这种情况下,函数的括号绝对是可选的。 You could be placed there seven if you like: (((((((function(){[...]}))))))) . 如果愿意,可以将您放置在七个位置: (((((((function(){[...]})))))))

The point here is that when you say «in the second one, the function/class "Person" is actually being called» you are WRONG there: That function, which acts as a constructor isn't being called by you . 此处的要点是,当您说“在第二个中,实际上正在调用函数/类” Person””时, 您就错了: 未在调用充当构造函数的函数。 You are simply passing it as a parameter (the constructor function) of the new operator which is, in fact, who is actually calling the constructor with the rest of parameters you provided, if any. 您只是将其作为运算符的参数(构造函数)传递,实际上,该运算符实际上是使用您提供的其余参数(如果有)调用构造函数。

See new syntax documentation : 请参阅新的语法文档

new constructor[([arguments])]

The constructor is the function you pass to the new operator and the parameters are specified between parentheses. 构造函数是传递给新运算符的函数,参数在括号之间指定。 But they are fully optional (including the parentheses itself). 但是它们是完全可选的(包括括号本身)。

This is why new constructor; 这就是为什么new constructor; without parentheses works. 没有括号的作品。

To be clear: What you thought happens (but not) would be written as: 要明确:您认为发生(但没有发生)的内容将写为:

var person = new ((function(){...})()) ();

...or, more verbosely: ...或更详细地说:

    var person = new (
        (function(){ // Constructor builder.
            [...]
            return function(){...}; // Actual constructor.
        })() // Constructor builder call
  //v-- Parentheses to force builder to be called.
    ) (); // <-- Parameters (if any) passed to the constructor.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM