2013-04-24 39 views
9

Một vấn đề rất khó hiểu tôi đang gặp phải với JavaScript. xem mã bên dưới ..Vấn đề về nhà xây dựng Javascript khó hiểu

az={ 
    classes:{ 
     test:function(){ 
     this.hello=function(name){ 
      alert('hello '+name); 
     } 
     } 
    }, 
    getClass:function(name){ 
    return az.classes[name]; 
    } 
}; 
var a=new az.classes['test'](); 
a.hello('foo'); 
var b= new az.getClass('test')(); 
b.hello();// fails !!! 

trong mã nếu bạn nhận thấy chúng tôi có một lớp được xác định bên trong một đối tượng az.classes. khi cố gắng tạo một thể hiện của lớp đó bằng cách mới az.classes['test](), nó hoạt động và a.hello() thực hiện tốt. nhưng khi tôi gọi phương thức az.getClass('test'), mà lần lượt trả về cùng một hàm tạo, nhưng nó không thành công khi tôi nói var b=new az.getClass('test'); ở đây câu nói của nó bundefined !! và b.hello() không thành công !! tôi không hiểu hành vi này! sự khác nhau giữa số mới az.classes['test']() và số mới az.getClass('test') là gì. Họ không giống nhau à ??

+1

thử 'var b = new (az.getClass ('test'))();' thay thế. sau đó b sẽ giống như một – user2264587

+0

@ gurvinder372 Bạn phải đọc một câu hỏi khác với tôi. Tôi thấy 'getClass: function (name)' – Phil

Trả lời

5

Khi khởi tạo một hàm tạo, các dấu ngoặc đơn đầu tiên chỉ ra những gì cần sử dụng tại hàm tạo.

Vì vậy, new az.classes['test'](); sẽ thực hiện biểu thức az.classes['test'] và sử dụng hàm kết quả làm hàm tạo.

Hoặc refactored, nó thực hiện điều này:

// new az.classes['test']() 
//      ^expression left of here used as constructor! 
var MyConstructor = az.classes['test']; 
new MyConstructor(); 

Tuy nhiên, new az.getClass('test')(); thực hiện biểu thức az.getClass trả về chức năng lớp getter của bạn, và cố gắng để sử dụng như là các nhà xây dựng. Sau đó, trường hợp của bạn đã cố gắng được thực hiện với ().

Hoặc refactored, nó thực hiện điều này:

// new az.getClass('test')(); 
//    ^expression left of here used as constructor! 
var MyConstructor = az.getClass; 
var instance = new MyConstructor('test'); 
instance(); // obviously not gonna work. 

Thấy sự khác biệt?

Bạn có thể giải quyết điều này bằng cách gói hơn parens xung quanh khái niệm đó nên trở về nhà xây dựng:

new (az.getClass('test'))(); 
//      ^expression left of here used as constructor! 

Hoặc bằng cách tiết kiệm các tài liệu tham khảo để xây dựng một biến địa phương, và sau đó sử dụng nó trên dòng tiếp theo. Điều này có thể lành mạnh và dễ đọc hơn:

var MyConstructor = az.getClass('test'); 
new MyConstructor(); 
//    ^expression left of here used as constructor! 
+0

Cool !! khám phá nó !! .. cảm ơn một triệu – user1179563

0

var b = new az.getClass('test')();

tương đương với đầu tiên nhận lớp:

var b = new az.classes.getClass('test'); 

b bây giờ là lớpaz.test, không phải là một thể hiện của nó .

và sau đó:

b = b(); 

gọi constructor lớp với đối tượng toàn cầu như thế này

3

Một chức năng xây dựng trong JavaScript có thể trả về một giá trị, thay thế giá trị mà thông thường sẽ được trả lại bởi " biểu thức mới ".

Vì vậy, new az.getClass("test")() trước tiên sẽ đánh giá az.getClass("test") sẽ trả về một hàm. Sau đó bạn sẽ gọi hàm đó với() sẽ trả về undefined vì nó không có giá trị trả về.

+0

+1 để trả lời câu hỏi – Phil

+0

+1, câu trả lời khác thực tế là sai - toán tử ưu tiên ra lệnh rằng 'new' được gọi sau'() '. –

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