Tôi nhận thấy rằng một số tập lệnh cũ mà tôi đang làm việc cho một dự án không hoạt động nữa sau khi nhóm của tôi nâng cấp lên Dojo 1.8. Cụ thể, biến toàn cầu mà chúng tạo ra không còn được tạo nữa.Dojo 1.8 - tạo biến toàn cục theo yêu cầu
Tôi đào xung quanh và phát hiện ra rằng nhóm Dojo 1.8 phản đối rất nhiều với các biến toàn cầu. Vì vậy, phản đối, trên thực tế, rằng họ làm cho nó thể chất không thể cho người sử dụng để tạo ra một biến toàn cầu trong một kịch bản yêu cầu sử dụng đoạn mã sau vào cuối của họ đòi hỏi:
req.eval =
function(text, hint){
return eval_(text + "\r\n////@ sourceURL=" + hint);
};
var eval_ = new Function('return eval(arguments[0]);');
Đó là tuyệt vời và tất cả, nhưng cái cũ mã tôi đang làm việc với không thể thay đổi, vì vậy tôi đã cố gắng tìm ra cách để có được xung quanh điều này và thực hiện eval trong bối cảnh cục bộ để thay thế.
May mắn thay, dojo.eval
vẫn còn ở đó từ các phiên bản cũ hơn của Dojo và điều đó thực hiện những gì tôi muốn. Vì vậy, tôi chỉ cần truy cập vào req.eval
và thay đổi chức năng để thực hiện return dojo.eval(...)
hoặc thậm chí chỉ eval(...)
trong một số trường hợp nhất định.
Vấn đề là, tôi chưa thể tìm ra cách truy cập vào req
. Đây là những gì sẽ xảy ra:
Tôi bao gồm dojo.js
trong thẻ tập lệnh ở đầu tệp HTML của tôi. Nó tải trong tập tin kịch bản riêng của nó.
dojo.require
có thể truy cập từ các tệp của riêng tôi. Nó được xác định với define
trong tệp tập lệnh:
'dojo/_base/loader':function(){
define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"], function(dojo, has, require, thisModule, json, lang, array) {
Tôi không chắc liệu điều đó có quan trọng hay không. Dù sao, trong phạm vi dojo.require
, tôi có thể thấy một cái gì đó gọi là injectModule
, trong khi trong tập tin của riêng tôi, tôi không thể. injectModule
là một biến địa phương để bạn không thể nhìn thấy nó với this
. Nó được định nghĩa trong một chức năng ẩn danh khi bắt đầu của tập tin, ví dụ:
(function(){ ... injectModule = function(){} ... })();
Bên trong injectModule
chức năng, có dòng sau:
req.getText(url, legacyMode!=sync, xhrCallback);
đó đi vào req.eval
. Vì vậy, injectModule
có thể xem req
.
Tôi không biết phải làm gì. Không có thủ thuật JavaScript bất chính nào của tôi đã giúp tôi thậm chí bắt đầu điều hướng khung lưới này. Một khởi đầu tốt sẽ là tìm cách xem injectModule
từ tập tin kịch bản bên ngoài của tôi gọi số dojo.require
. Mặc dù vậy, tôi đã không thể làm điều đó với 'bind', bởi vì nó là một biến cục bộ được định nghĩa trong một hàm ẩn danh. Điều này thậm chí sẽ có thể?
Để làm cho mọi việc dễ dàng hơn một chút, đây là một bản tóm tắt:
Tập 1:
<script src="dojo.js"></script>
dojo.require(File 3);
console.log(globalVar);
Tập 2:
(function(){req.eval = unhelpful function})();
define(["require"], function(module){
dojo.require = function(x){req.eval(x)}
});
Tập 3:
globalVar = ...;
tôi có thể sửa đổi tập tin 1 và 3, nhưng tập tin 3 wi sẽ luôn luôn cần một biến toàn cầu. Tôi không thể sửa đổi tập tin 2. Mục tiêu là thay đổi req.eval
trong tệp 2 thành một chức năng tốt hơn.
Khai báo biến toàn cầu trước đó không hoạt động do thay đổi phạm vi có nghĩa là tệp 3 vẫn không thể xem được.
Phản ánh và thay thế chuỗi không hoạt động vì phạm vi sai và JS được rút gọn ở phía máy chủ.
Ghi đè các phương thức từ tệp 1 không hoạt động vì tôi không thể nhìn thấy thông qua phạm vi.
Sử dụng chức năng JavaScript bind
cũng không có hiệu quả.
Các bạn đã thử 'window.globalVar = 42' trong tập tin 3? – James
Tôi đã không làm việc đó, cảm ơn bạn. Tôi không thực sự hiểu làm thế nào 'n = 5' và' window.n = 5' kết thúc là khác nhau. –