Mã của bạn theo thứ tự bạn đã trích dẫn, phải không? Singleton xuất hiện phía trên RequestManager
trong nguồn?
Nếu có, đó là vấn đề của bạn. (!) Đó là khá tinh tế, nhưng giả sử hai bạn bit mã được niêm yết theo thứ tự bạn đã cho họ thấy, đây là thứ tự mà sự việc xảy ra (tôi sẽ giải thích nó dưới lên):
- Chức năng
RequestManager
được xác định.
- Chức năng ẩn danh của bạn tạo ra các lần chạy đơn lẻ của bạn, bao gồm việc khởi tạo phiên bản
RequestManager
.
- Nguyên mẫu
RequestManager
được thay thế bằng nguyên mẫu mới.
Kể từ khi dụ myRequestManager
được instantiated trước nguyên mẫu đã được thay đổi, nó không có các chức năng bạn đã định nghĩa trên đó (mới) nguyên mẫu. Nó tiếp tục sử dụng đối tượng nguyên mẫu đã được đặt ra khi nó được khởi tạo.
Bạn có thể khắc phục điều này dễ dàng bằng cách sắp xếp lại mã, hoặc bằng cách thêm thuộc tính để RequestManager
's nguyên mẫu chứ không phải thay thế nó, ví dụ:
RequestManager.prototype.require = function(text){
//make an ajax request
};
RequestManager.prototype.otherFunc = function(){
//do other things
};
đó làm việc vì bạn chưa thay sự đối tượng nguyên mẫu, bạn vừa thêm vào nó. myRequestManager
thấy các bổ sung bởi vì bạn đã thêm chúng vào đối tượng mà nó đang sử dụng (thay vì thiết lập một đối tượng mới trên hàm thuộc tính của hàm xây dựng là thuộc tính prototype
).
Tại sao điều này xảy ra hơi kỹ thuật và tôi hầu như sẽ trì hoãn thông số kỹ thuật. Khi trình thông dịch nhập vào "ngữ cảnh thực thi" mới (ví dụ: một hàm hoặc toàn cảnh — ví dụ, trang — ngữ cảnh), thứ tự mà nó thực hiện không phải là thứ tự nguồn từ trên xuống nghiêm ngặt, có các giai đoạn . Một trong những giai đoạn đầu tiên là khởi tạo tất cả các hàm được định nghĩa trong ngữ cảnh; điều đó xảy ra trước khi bất kỳ mã từng bước nào được thực hiện. Chi tiết trong tất cả vinh quang của chúng trong phần 10.4.1 (mã toàn cầu), 10.4.3 (mã chức năng) và 10.5 (ràng buộc khai báo) trong the spec, nhưng về cơ bản, các hàm được tạo trước dòng đầu tiên của mã từng bước.:-)
Đây là đơn giản nhất để xem với một ví dụ thử nghiệm cách ly:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Test Page</title>
<style type='text/css'>
body {
font-family: sans-serif;
}
</style>
<script type='text/javascript'>
// Uses Thing1
var User1 = (function() {
var thing1 = new Thing1();
function useIt() {
alert(thing1.foo());
}
return useIt;
})();
// Uses Thing2
var User2 = (function() {
var thing2 = new Thing2();
function useIt() {
alert(thing2.foo());
}
return useIt;
})();
// Thing1 gets its prototype *replaced*
function Thing1() {
this.name = "Thing1";
}
Thing1.prototype = {
foo: function() {
return this.name;
}
};
// Thing2 gets its prototype *augmented*
function Thing2() {
this.name = "Thing2";
}
Thing2.prototype.foo = function() {
return this.name;
};
// Set up to use them
window.onload = function() {
document.getElementById('btnGo').onclick = go;
}
// Test!
function go() {
alert("About to use User1");
try
{
User1();
}
catch (e)
{
alert("Error with User1: " + (e.message ? e.message : String(e)));
}
alert("About to use User2");
try
{
User2();
}
catch (e)
{
alert("Error with User2: " + (e.message ? e.message : String(e)));
}
}
</script>
</head>
<body><div>
<div id='log'></div>
<input type='button' id='btnGo' value='Go'>
</div></body>
</html>
Như bạn có thể thấy nếu bạn chạy nó, User1
thất bại vì Thing1
dụ nó đang sử dụng không có một tài sản foo
(vì nguyên mẫu đã được thay thế), nhưng User2
hoạt động vì trường hợp Thing2
nó sử dụng * (vì nguyên mẫu được tăng cường, không được thay thế).
Tôi không nhận được lỗi ... Các tham số 'đến từ đâu khi bạn xây dựng RequestManager? –
Trong mẫu mã bạn cung cấp, thông số không được xác định. Bạn đã để lại một cái gì đó trong ví dụ của bạn? – Robusto