2012-03-19 29 views
20

Mã nghiêm ngặt và không nghiêm ngặt có thể được trộn lẫn. Nhưng bạn không thể sử dụng người gọi ngay cả khi cuộc gọi đến không phải là mã nghiêm ngặt. Có ai biết cách giải quyết nào không?Cách nhận người gọi từ chế độ nghiêm ngặt?

Tôi cố gắng này:

(function strict(){ 
    "use strict"; 
    nonStrict();//ok 
    nonStrictCaller();//error :(
})(); 

function nonStrict(){ 
    return 011;//Octal literals are not allowed in strict mode 
} 

function nonStrictCaller(){ 
    return nonStrictCaller.caller; 
} 
+1

Bạn có thể vượt qua 'this' đến chức năng, có thể không? – gdoron

+0

Tôi nghĩ bạn có thể muốn xem ở đây, đặc biệt là trong các bình luận http://stackoverflow.com/a/280396/575527 – Joseph

+0

Cách giải quyết là làm cho mã của bạn tuân thủ chế độ nghiêm ngặt. Đó là loại điểm của chế độ nghiêm ngặt; * nó nghiêm ngặt *. Trong trường hợp của bạn, điều đó có nghĩa là làm cho người gọi có thể truy cập bằng một số phương tiện khác, như chuyển nó qua tên như một đối số. –

Trả lời

11

Dưới đây là một hack ác mà chỉ hoạt động trong động cơ V8. Phiên bản 140 bytes:

function x(a,b,c){function d(e,f){d=f}c=(b=Error)[a='prepareStackTrace'];b.captureStackTrace(b[a]=d,x);d.stack;b[a]=c;return d} 

Và phiên bản ít khó hiểu

if ('captureStackTrace' in Error) { 
    void function(){ 
    function prepare(e, callsites){ 
     return callsites; 
    } 

    function stack(f){ 
     var e = {}; 
     var oldPrepare = Error.prepareStackTrace; 
     Error.prepareStackTrace = prepare; 
     Error.captureStackTrace(e, f || stack.caller); 
     e = e.stack; 
     Error.prepareStackTrace = oldPrepare; 
     return e; 
    } 

    function lastReceiver(){ 
     return stack(lastReceiver)[2].receiver; 
    } 

    var CallSite = stack()[0].constructor; 
    var callsiteMethods = {}; 

    Object.getOwnPropertyNames(CallSite.prototype).forEach(function(key){ 
     if (/^is|^get/.test(key)) { 
     callsiteMethods[key.replace(/^is|^get/, '')] = CallSite.prototype[key]; 
     } 
     callsiteMethods.location = CallSite.prototype.toString; 
    }); 

    CallSite.prototype.resolve = function resolve(){ 
     for (var k in callsiteMethods) 
     this[k] = callsiteMethods[k].call(this); 
    } 

    }(); 
} 
+3

Điều này dường như không hoạt động trong Chrome nữa. :-\ ví dụ. http://jsbin.com/zifadipivo/12/?v8Hack=true –

Các vấn đề liên quan