2013-03-16 11 views
10

Tôi biết không nên sử dụng đối tượng toàn cục và toàn bộ ý tưởng đằng sau việc sử dụng AMD là tránh sử dụng đối tượng chung. Nhưng đối với một số mã di sản, tôi phải xác định một số nội dung trong đối tượng chung. Hiện nay các mã trông như thế này:truy cập đối tượng toàn cầu khi sử dụng requirejs

//example2.js 
define(function(){ 
    var globalObject = window; 
    globalObject.x = ... 
    globalObject.y = ... 
}); 

Nó hoạt động nhưng cứng mã hóa các đối tượng toàn cầu window không trông rất đẹp và tôi tò mò để xem nếu nó có thể loại bỏ nó. Khi define() không được sử dụng, mã trông như thế này:

//example1.js 
x = ... 
y = ... 

Tôi biết, tôi biết bạn ghét mã này, nhưng chúng ta hãy vào vấn đề: làm thế nào biến toàn cầu có thể được truy cập một cách có cấu trúc bên trong define() chức năng trong requirejs? Tôi muốn có một cái gì đó giống như một tham số cuối cùng ẩn để các chức năng đó được truyền cho define() như thế này:

//example3.js 
define(function(globalObject){ 
    globalObject.x = ... 
    globalObject.y = ... 
}); 

Hoặc thậm chí đơn giản hơn: biến this sẽ trỏ đến đối tượng toàn cầu bên trong hàm đó. Ví dụ:

//example4.js 
define(function(){ 
    this.x = ... 
    this.y = ... 
}); 

Lưu ý: Tôi không chắc chắn về người cuối cùng này. Điều tra biến số this bên trong hàm được chuyển đến require() nói rằng nó bằng window có thể là câu trả lời cho câu hỏi của tôi, nhưng tôi không thể tìm thấy bất kỳ tài liệu nào đề cập đến ngữ cảnh mà hàm đã truyền đang chạy. Có lẽ nó đang chạy trong bối cảnh của biến toàn cầu sau khi tất cả?

Trả lời

5

Nếu bạn không ở chế độ nghiêm ngặt, bạn có thể làm điều này:

(function() { 
    var global = this; 

    define(function(){ 
    global.x = ... 
    global.y = ... 
    }); 
})(); 

Các chức năng ẩn danh bên ngoài mà chúng ta ngay lập tức gọi được gọi không có giá trị đặc biệt this đặc biệt, và như vậy (vì đây không phải là ở chế độ nghiêm ngặt), nhận đối tượng chung là this. Vì vậy, chúng tôi lấy this thành một biến (global) trong chức năng ẩn danh, và sử dụng nó từ chức năng bạn chuyển vào define (đóng trên nó).

+0

đây là một ý tưởng hay, nhưng tôi vẫn tự hỏi liệu có một cơ chế từ bên trong hàm 'define()' không yêu cầu nhúng mã của tôi trong một hàm gọi ngay lập tức? – AlexStack

13

Tôi đề nghị bạn tạo mô-đun trả về đối tượng window. Điều này đặc biệt hữu ích cho các mục đích thử nghiệm đơn vị (phụ thuộc chế nhạo).

window.js

define(function(){ 
    return window; 
}); 

app.js

define(['window'], function(win) { 
    // Manipulate window properties 
    win.foo = 1; 
    console.log(win.foo);  
}); 
+0

vì vậy nếu bạn thực sự muốn đối tượng chung như bạn muốn mô-đun của bạn chạy một ngữ cảnh khác thì sao? – gman

+0

Nếu tôi hiểu chính xác bạn @gman ... hãy nói mã của chúng tôi nằm trong iframe nhưng chúng tôi cần đối tượng toàn cầu hàng đầu. Chúng ta có thể làm điều này: '// Mã bên trong iframe xác định ([ 'cửa sổ'], function (win) {var Topwin = win.top; // Thao tác cửa sổ thuộc tính iframe của win.foo = 1; console.log (win.foo); // Thao tác trên cửa sổ thuộc tính topWin.foo = 2; console.log (topWin.foo); }); ' –

+0

xin lỗi, tôi có nghĩa là tôi sẽ không chạy trong trình duyệt để đối tượng toàn cục không phải là 'window' – gman

5

Một biến thể của câu trả lời @ TJCrowder, mà cũng làm việc trong chế độ nghiêm ngặt:

(function(global) { 
    define(function() { 

     global.a="this"; 
     global.b="that"; 

    }); 
})(this); 

Bằng gọi func gọi ngay lập tức tion với đối số 'this' (mà bên ngoài một hàm là phạm vi toàn cục), thì bất kể phạm vi toàn cục nào được truyền vào IIF làm đối số 'toàn cục'.

Điều này cũng tránh khó mã hóa đối tượng 'cửa sổ', một lợi thế vì điều đó không áp dụng trong môi trường không phải trình duyệt.

+0

Nếu tôi đặt mã đó vào một tập tin và chuyển nó vào Node, 'this' là' {} ', có hay không tôi đang ở chế độ nghiêm ngặt. – Louis