2012-02-16 38 views
12

tôi đã trả lời một câu hỏi về việc đóng cửa ở đây trong SO với mẫu này:tạo đối tượng từ đóng JS: tôi có nên sử dụng từ khóa "mới" không?

function Constructor() { 
    var privateProperty = 'private'; 
    var privateMethod = function(){ 
     alert('called from public method'); 
    }; 
    return { 
     publicProperty: 'im public', 
     publicMethod: function(){ 
      alert('called from public method'); 
     }, 
     getter: privateMethod 
    } 
} 

var myObj = new Constructor(); 

//public 
var pubProp = myObj.publicProperty; 
myObj.publicMethod(); 
myObj.getter(); 

//private - will cause errors 
myObj.privateProperty 
myObj.privateMethod 

một người dùng nhận xét về câu trả lời của tôi nói:

Ngoài ra, nếu chức năng của bạn trả về một cách rõ ràng một đối tượng nó không phải là một tốt thực hành để gọi nó với mới bởi vì đó là lừa dối - nếu sử dụng mới mà bạn mong đợi kết quả là một thể hiện của Constructor

tôi thường tạo các đối tượng bằng cách sử dụng mới. nhưng tại sao lại là không phải là một thực hành tốt? nó có vẻ như sử dụng mới và không sử dụng lợi nhuận mới cùng một điều. cách thích hợp để tạo các đối tượng từ bao đóng là gì?

Trả lời

11

Không, nó không giống nhau. Cân nhắc khi sử dụng instanceof:

function C1() { 
    return {}; 
} 

function C2() { 
} 

var c1 = new C1(); 
var c2 = new C2(); 
alert(c1 instanceof C1); // false; wha...? 
alert(c2 instanceof C2); // true, as you'd expect. 

Here's a demo.

Vì vậy, thay vào đó, tạo ra chúng bằng cách gán cho this, có thể với một bảo vệ để ngăn chặn lãng quên new s.

function Constructor() { 
    var privateProperty = 'private'; 
    var privateMethod = function() { 
     alert('Called from private method'); 
    }; 

    this.publicProperty = "I'm public!"; 
    this.publicMethod = function() { 
     alert('Called from public method'); 
    }; 
    this.getter = privateMethod; 
} 

Thậm chí tốt hơn, sử dụng nguyên mẫu khi có thể:

function Constructor() { 
    var privateProperty = 'private'; 
    var privateMethod = function() { 
     alert('Called from private method'); 
    }; 

    this.getter = privateMethod; 
} 

Constructor.prototype.publicProperty = "I'm public!"; 
Constructor.prototype.publicMethod = function() { 
    alert('Called from public method'); 
}; 
+0

như sau: http://jsfiddle.net/DZTC8/1/ cả hai đều trả về cùng một điều, có hoặc không có 'mới' – Joseph

+4

@Joseph: Quan điểm của tôi là nó làm cho' instanceof' hành động kỳ lạ. Đối tượng trả về là * không phải là một cá thể của hàm tạo *, như một người dùng mong đợi, mà đúng hơn là một đối tượng. – Ryan

+0

+1 cho "lạ". cảm ơn! bây giờ tôi có được ý tưởng. – Joseph

2

xem xét điểm 4 từ câu trả lời này: What is the 'new' keyword in JavaScript?

"Nó trả về đối tượng mới được tạo ra, trừ khi chức năng constructor trả về một tổ chức phi Trong trường hợp này, giá trị không nguyên thủy đó sẽ được trả về. "

Vì vậy, như hàm C1 từ câu trả lời của minitech trả về một đối tượng trống, biến c1 sẽ là đối tượng được trả về và không phải là biến được tạo bởi câu lệnh 'mới'. Do đó không có thể hiện của hàm constructor.

Nếu tôi cố trả về giá trị nguyên thủy từ hàm khởi tạo, webstorm của tôi cho tôi biết: "Khi được gọi với giá trị mới, giá trị này sẽ bị mất và đối tượng sẽ được trả về".

Các vấn đề liên quan