2011-12-23 25 views
6

xem xét mã này:Có sử dụng mới trong Javascript giống như không sử dụng không?

function klass(z) { 
    this.a = z; 
    return this; 
} 

var b = klass(5); 
var c = new klass(9);

Khi tôi chạy nó trong Chrome và kiểm tra trong giao diện điều khiển, b hóa ra là loại DOMWindow, trong khi c là loại klass.

Mặc dù cả hai đều có thuộc tính a, có hiệu quả cả hai là một ví dụ của klass.

  • Có sử dụng hoặc không sử dụng mới, giống nhau không?
  • Giống như trên ví dụ này nhưng khác nhau trong các tình huống khác?
  • Có sự khác biệt về hiệu quả hoặc hành vi không?
+0

đẹp câu hỏi, tôi muốn biết điều này quá. –

+3

Chỉ cần từ các thông tin trong câu hỏi của bạn rõ ràng là không giống nhau, bởi vì các đối tượng kết quả có các loại khác nhau. Nếu bạn điều tra những gì thuộc tính _other_ cái đầu tiên bạn sẽ thấy sự khác biệt ... – nnnnnn

Trả lời

6

Khi một hàm được gọi như thế này

klass(6); //called function invocation 

this sẽ được thiết lập để các đối tượng toàn cầu, hoặc, nếu bạn đang ở chế độ nghiêm ngặt, undefined

Kết quả là, người đầu tiên ví dụ (không có new) sẽ trả lại đối tượng chung với thuộc tính mới a được đính kèm. Ở chế độ nghiêm ngặt, nó sẽ ném một lỗi vì this sẽ được đặt thành undefined và bạn không thể thêm thuộc tính a vào undefined.

Khi bạn gọi một hàm với new

new klass(9); //called constructor invocation 

giá trị this được thiết lập để một đối tượng mới, và là ngầm trở từ chức năng-không cần phải nói return this

Đối với đầy đủ , khi bạn gọi hàm là phương thức trên đối tượng:

foo.method(); //called method invocation 

this sẽ được đặt thành đối tượng— foo trong trường hợp này.

Và khi bạn gọi một hàm với áp dụng (hoặc gọi)

method.apply(foo) //called apply invocation 

this được thiết lập để bất cứ điều gì bạn specify- foo lại

EDIT

tôi đã đề cập trong câu trả lời của tôi strict mode . Một trang sử dụng chế độ nghiêm ngặt nếu nó có

"use strict" 

ở trên cùng của nó.

+0

Làm thế nào để tôi có được chế độ nghiêm ngặt? – Thilo

+1

@Thilo - xem chỉnh sửa –

+0

+1, nhưng trong đoạn thứ hai của bạn, tôi nghĩ bạn có nghĩa là "' this' sẽ được đặt ... " – nnnnnn

3

Nó hoàn toàn không giống nhau:

var a = klass(42); 
console.log(a.a); // 42 
var b = klass(69); 
console.log(b.a); // 69 
console.log(a.a); // 69 

Nếu bạn không gọi new, bạn không nhận được bất cứ điều gì mới.

+1

* "Nếu bạn không gọi mới, bạn sẽ không nhận được bất kỳ điều gì mới." * Sâu sắc trong sự đơn giản của nó. :) –

+0

Nhưng tất nhiên bạn có thể tạo các đối tượng mới mà không có 'mới' trong JS. – Kos

6

Nếu không có new, chức năng của bạn sẽ hoạt động trên bất kỳ số this nào bị ràng buộc, trong trường hợp của bạn là DOMWindow. Không có cá thể mới được tạo, thuộc tính a được đặt trên đối tượng cửa sổ. Gọi phương thức hai lần sẽ ghi lại kết quả trước đó.

Hãy thử điều này:

var b = klass(5) 
log.info(b.a) 
log.info(b == window) // b is actually the window object 
log.info(window.a) // also 5 

var c = klass(6) 
log.info(b.a)  // now set to 6 
log.info(c == b) // c and b are the same 
Các vấn đề liên quan