2013-05-30 27 views
8

Tôi đã đọc Thiết kế trò chơi với HTML5 và JavaScript và nó đã giới thiệu tôi với các đối tượng. Vì vậy, sau khi đọc cuốn sách và làm việc trên các dự án, tôi quyết định thực hiện kiến ​​thức mới này và tích hợp các đối tượng trong các dự án của riêng tôi. Vì vậy, đây là câu hỏi của tôi có thể hoặc nên các đối tượng gọi chức năng riêng của họ? Ví dụ:Chức năng gọi đối tượng Javascript từ chính nó

var someObject = { 
    start: function() { 
     check(); 
    }, 
    check: function() { 
     console.log("Check!"); 
    } 
}; 

someObject.start(); 

Cuốn sách này đã cho thấy một ví dụ với một bộ đếm thời gian mà thực hiện điều này:

var timer = { 
    start: function() { 
     var self = this; 
     window.setInterval(function(){self.tick();}, 1000); 
    }, 
    tick: function() { 
     console.log('tick!'); 
    } 
}; 

Trong ví dụ với bộ đếm thời gian đối tượng nó làm cho một tham chiếu đến tự để gọi hàm nội bộ, do đó, điều này có nghĩa là tôi nên sử dụng tự để gọi chức năng nội bộ hoặc là điều này đúng cách để làm điều này với các đối tượng? Hoặc thực hành tốt nhất? Cảm ơn trước.

var someObject = { 
    start: function() { 
     var self = this; 
     self.check(); 
    }, 
    check: function() { 
     console.log("Check!"); 
    } 
}; 

someObject.start(); 
+3

Lý do họ sử dụng nó trong 'dụ setTimeout' là vì callback của nó được thực hiện trong phạm vi toàn cầu, vì vậy giá trị của' this' trong 'setTimeout' gọi lại là 'cửa sổ'. Để giữ một tham chiếu đến đối tượng ban đầu, bạn phải sử dụng phương thức đó (lưu trữ nó trong 'self') hoặc một số dạng sử dụng' Function.bind() ' – Ian

Trả lời

5

Tên JavaScript là lexically scoped, vì vậy bất cứ khi nào một tên (biến) gặp phải trong tập lệnh, thời gian chạy JavaScript phải tìm kiếm các phạm vi từ vị trí hàm được xác định.

Tại điểm của định nghĩa, chức năng này:

start: function() { 
    check(); 
} 

không có quyền truy cập vào bất kỳ chức năng check trong phạm vi bên ngoài của nó. Khai báo self và liên kết nó với this là một kỹ thuật được sử dụng để xử lý (hơi thú vị) intricacies of referring to the current object in JavaScript (vì mã ví dụ sử dụng window.setInterval).

Để tham chiếu hàm trong đối tượng hiện tại, đủ để sử dụng this.

var someObject = { 
    start: function() { 
     this.check(); 
    }, 
    check: function() { 
     console.log("Check!"); 
    } 
}; 
0

Tất nhiên một đối tượng có thể và nên gọi đó là chức năng riêng, đây là cách duy nhất để mô phỏng OOP trong javascript. Tôi sẽ nói rằng thực tế mà cuốn sách đang sử dụng, self = this là xấu vì this chỉ có thể được sử dụng bởi chính nó, tuy nhiên trong ví dụ đầu tiên nó được sử dụng để bảo tồn giá trị của điều này mà nếu không sẽ là this của chính nó. lớp bên ngoài

+0

" mô phỏng "; chỉ cần nói với chính mình rằng, có thể nhấp vào gót chân của bạn với nhau trong khi bạn nói ... – dandavis

+0

Có nhiều lý do để thực hiện 'var self = this'; một lý do hoàn toàn không liên quan là làm cho kịch bản nén hiệu quả hơn. – voithos

+0

@voithos đọc toàn bộ câu trả lời Tôi chỉ nói việc sử dụng thứ hai là xấu – aaronman

1

Điểm khai báo và khởi tạo biến như "tự" là đối phó với thực tế là giá trị của this được xác định lại sau mỗi lần gọi hàm. Khi bạn có hàm lồng trong hàm khác và hàm bên trong đó cần quyền truy cập vào giá trị this từ ngữ cảnh bên ngoài, thì this phải được giữ nguyên trong một biến khác — "tự" trong trường hợp của bạn. (Tên của biến đó là không quan trọng của khóa học.)

Trong mã mẫu của bạn:

var timer = { 
    start: function() { 
     var self = this; 
     window.setInterval(function(){self.tick();}, 1000); 
    }, 
    tick: function() { 
     console.log('tick!'); 
    } 
}; 

rằng chức năng thông qua vào setInterval() nhu cầu sử dụng giá trị của this từ "bắt đầu" chức năng. Tuy nhiên, khi chức năng hẹn giờ khoảng thời gian đó được gọi, this được đặt thành một thứ khác (ngữ cảnh chung hoặc null ở chế độ "nghiêm ngặt"). Vì vậy, bằng cách lưu giá trị của this trong ngữ cảnh mà chức năng hẹn giờ khoảng thời gian đó được khởi tạo, mã của nó có thể sử dụng nó để truy cập đối tượng bộ đếm thời gian.

Trong ví dụ thứ hai của bạn, việc khai báo và khởi tạo biến "tự" không làm tổn hại gì, nhưng không cần thiết. Đôi khi nó tiện dụng tuy nhiên, chỉ để làm rõ mã, mặc dù tất nhiên một tên có ý nghĩa hơn so với "tự" sẽ là một ý tưởng tốt.

+0

Đó không phải là những gì đang làm trong ví dụ thứ hai mặc dù – aaronman

+0

@aaronman vâng, đó là sự thật. – Pointy

1

Ngữ cảnh hàm javascript, mỗi khi bạn tạo hàm, bạn tạo ngữ cảnh (phạm vi) mới.

Trong setInterval() chức năng bạn tạo một phạm vi mới, vì vậy this không còn tham khảo như cùng this trên:

var self = this; 
setInterval(function() { 
    self.tick(); 
}, 1000); 

Bạn cũng có thể tự ràng buộc ngữ cảnh thích hợp của chức năng của bạn với bind() (do đó bạn không cần self nữa):

setInterval(function() { 
    this.tick(); 
}.bind(this), 1000); 

Mọi thông tin: