2016-10-27 16 views
0

newの動作は、下の2つの例でどのように異なっていますか?私は、2番目の例は、変数とannoymous funcitonを置き換えているが、2番目の関数/クラス "Person"は実際に呼び出されていることがわかります。それが呼び出されているかどうかは違いますか?私はそれを呼び出しなくても試しましたが、それはまだ働いていました。新しいことが実際に関数を呼び出し、thisをインスタンス変数に割り当てるように設定していると私は考えました。重要ではありません:それは変数に割り当てられているかどうかは"new"はどのようにJavaScriptのクラスで動作しますか?

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

+0

はいえ(JavaScriptでは授業はありません*クラス*構文があります)。どのようにして最初の例で2番目のインスタンスを作成しますか? – RobG

+0

関連する並べ替え:http://stackoverflow.com/questions/6750880/how-does-the-new-operator-work-in-javascript、および、http://stackoverflow.com/questions/1646698/what- new-keyword-in-javascript – PicoCreator

答えて

2

それは、このような単純な関数であった場合には、この2つの例の間にほとんど差はないだろう:

(function() { console.log("IIFE"); })(); 
 

 
// or 
 

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

あなただけの変数にあなたの関数を保存し、それを呼び出します。

それはJS OOPのメカニズムに関連しているので、しかし、それは、少し違いになります。最初のケースではObjectインスタンスを取得し、2番目のインスタンスではPersonインスタンスを取得します。これは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);

newとクラスはJS OOPの全機能を有効にするために、第2の場合のように使用することになっています。匿名クラスのコンストラクタの使用には全く意味がありません。

+0

constructorプロパティと* instanceof *は、オブジェクトが特定の「クラス」のインスタンスであるかどうかを判断する信頼性のない方法です。例えば。 'var Fred = Person; var fred = new Fred; fred.constructor.name // Person'を返します。 – RobG

1

。これは、この例に完全に平行である:

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

console.log(1); 

それが呼び出さする必要があるかどうか:new演算子と関数が常に呼び出されているが、newで、括弧は任意ですパラメータが渡されない場合:new Person()new Personに相当しますが、new Person("Joe")は異なる方法では実行できません。

1

2番目の例では、新しいオペレータの正確な機能をに渡しています。単にリテラル関数を直接書くのではなく、(変数に論理的に格納された)参照を使うだけです。

だから、あなたの第二の例は、同じあるとして:

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

どの、実際には、非常に最初のものと同じである:

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

NOTEことこの場合、関数を取り囲む括弧は絶対にオプションです。あなたが好きなら、あなたはそこに7人置くことができます:(((((((function(){[...]})))))))

ここでのポイントは、あなたが«2つ目の関数/クラス 『人』では実際に呼び出されている»と言うとき、あなたがそこに間違っているということです。コンストラクタとして働きその関数、によって呼び出されていません。実際には、提供した残りのパラメータがあればそれを実際にコンストラクタを呼び出しているのは、新しい演算子のパラメータ(コンストラクタ関数)として渡すだけです。

new syntax documentationを参照してください:

new constructor[([arguments])] 

コンストラクタでは、新しい演算子に渡す関数であり、パラメータは括弧の間に指定されています。しかし、それらは完全にオプションです(かっこを含む)。

このため、かっこなしのnew constructor;が機能します。あなたが起こると思った(ではない)とは何のように書かれます:

は明確にすることが

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

...または、より冗長:

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. 
関連する問題