2010-02-26 41 views
39

Pragma chế độ nghiêm ngặt có trong ECMAScript5 là bao nhiêu?Trong ECMAScript5, phạm vi "sử dụng nghiêm ngặt" là gì?

"use strict"; 

Tôi muốn làm điều này (chủ yếu là do JSLint không phàn nàn về nó):

"use strict"; 

(function() { 
    // my stuff here... 
}()); 

Nhưng tôi không chắc chắn nếu điều đó sẽ phá vỡ các mã khác hay không. Tôi biết rằng tôi có thể làm được điều này, mà sẽ phạm vi các pragma đến chức năng ...

(function() { 

    "use strict"; 

    // my stuff here... 

}()); 

nhưng JSLint phàn nàn về nó (khi JSLint tùy chọn "nghiêm ngặt" được kích hoạt) vì nó nghĩ rằng bạn đang thực thi mã trước khi bạn bật "sử dụng nghiêm ngặt".

Đây là câu hỏi của tôi. Nếu tôi có fileA.js:

"use strict"; 
// do some stuff 

và fileB.js:

eval(somecodesnippet); // disallowed by "use strict" 

và sau đó đưa vào trang html của tôi trong cùng một thứ tự đó, pragma sẽ được scoped đến tập tin, hoặc sẽ pragma chảy máu vào fileB, do đó ngăn chặn việc thực thi eval?

+0

Một bên Lưu ý: Bài thuyết trình của Douglad Crockford về "Nhà nước và tương lai của Javascript thực sự tuyệt vời. Anh ấy thảo luận về một số tính năng mới như nghiêm ngặt vào cuối buổi nói chuyện. Đây là liên kết: http://www.infoq.com/presentations/The-State-and-Future-of-JavaScript –

+0

'eval()' được cho phép với '" sử dụng nghiêm ngặt "', nó chỉ được đưa vào phạm vi toàn cầu. –

Trả lời

2

EDIT Có vẻ như tôi đã sai. Vui lòng xem Jeff Walden's answer below.

Kiểm tra câu trả lời này cho một câu hỏi liên quan: What does "use strict" do in JavaScript, and what is the reasoning behind it?

Mặc dù khiếu nại JSLint, bạn có thể (và nên ) sử dụng "use strict"; bên trong một hàm nếu bạn chỉ muốn chức năng đó để được ở chế độ nghiêm ngặt. Nếu bạn sử dụng nó trong bối cảnh toàn cầu thì nó sẽ buộc tất cả mã của bạn phải ở chế độ nghiêm ngặt. Câu trả lời ngắn: có, nó sẽ chặn việc bạn sử dụng eval.

+2

Câu trả lời này không đúng. Sử dụng chỉ thị ở đầu tệp 'fileA.js' làm cho toàn bộ tệp đó ở chế độ nghiêm ngặt, nhưng nó không gây ra' fileB.js' ở chế độ nghiêm ngặt, bất kể thứ tự chúng được bao gồm trong trang HTML . Hơn nữa, 'eval()' hoạt động khác ở chế độ nghiêm ngặt, nhưng nó vẫn hoạt động. Nó không phải là "bị chặn". –

54

"use strict" chỉ áp dụng cho phạm vi chức năng hoặc chương trình. Vì vậy, nếu bạn có fileA.js với "use strict" ở trên cùng, fileA.js thực thi ở chế độ nghiêm ngặt và tất cả các hàm được định nghĩa trong nó sẽ thực hiện tương tự khi được gọi. Nhưng fileB.js là một chương trình riêng biệt, do đó, "use strict" từ fileA.js không áp dụng cho nó - và do đó fileB.js sẽ thực thi ở chế độ không nghiêm ngặt. (Tất nhiên, nếu somecodesnippet bắt đầu bằng chỉ thị "use strict" và phân tích cú pháp chính xác, mã đó sẽ thực thi ở chế độ nghiêm ngặt và các hàm do mã đó xác định cũng sẽ thực hiện tương tự.) Tính nghiêm ngặt hoàn toàn không "chảy máu" - và mỗi ES5 4.2.2 (thừa nhận là không quy chuẩn, nhưng tôi chắc chắn rằng tôi có thể khai thác một tham chiếu quy phạm cho điều này nếu cần thiết), "việc triển khai phải hỗ trợ kết hợp các đơn vị mã chế độ không hạn chế và nghiêm ngặt vào một chương trình tổng hợp duy nhất".

Một trong những lưu ý này: nếu bạn sử dụng chế độ nghiêm ngặt trong phạm vi toàn cầu đôi khi nhưng không phải lúc nào, bạn không còn có thể nối các tập lệnh của mình thành một tệp nữa. Giả sử bạn có các tập lệnh A, B, C, D theo thứ tự đó. Nếu A là nghiêm ngặt, việc ghép nối tổng thể sẽ được nghiêm ngặt, ngay cả khi B/C/D không! Ngược lại, nếu A không nghiêm ngặt (và không trống), việc ghép nối chung sẽ không nghiêm ngặt, ngay cả khi B/C/D là nghiêm ngặt. Điều này đã cắn ít nhất một trang web nhận con nuôi sớm ra khỏi đó.

Tất cả những gì đã nói, chế độ nghiêm ngặt không cấm eval.Khi eval được gọi là cách thông thường ở chế độ nghiêm ngặt, sử dụng cú pháp chương trình của biểu mẫu eval(code [, ...]), đó là eval "trực tiếp" hoạt động theo cách eval luôn có - ngoại trừ code luôn được đánh giá là mã chế độ nghiêm ngặt, ngay cả khi code doesn ' t bắt đầu với chỉ thị "use strict" và ngoại trừ bất kỳ biến nào được tạo bởi mã được lưu trữ trong bộ nhớ riêng của chúng từ bất kỳ biến hiện có nào. (Ngữ nghĩa chính xác có chút phức tạp; Tôi làm việc trên công cụ JavaScript của Firefox, sau khi triển khai công cụ này, và thậm chí sau một khoảng thời gian hợp lý trong thông số kỹ thuật và thực hiện nó vẫn không trực quan với tôi.)

Nếu nó không được gọi theo cách đó - eval.call(...), setTimeout(eval, ...), setInterval(eval, ...), var ev = eval; ev(...);, v.v. - đó là eval "gián tiếp". Gián tiếp eval (cho dù bên trong hay bên ngoài chế độ nghiêm ngặt) hoạt động một chút khác nhau: độ phân giải tên và định nghĩa biến xảy ra như thể trong phạm vi toàn cầu. (Mã sẽ chỉ thi hành dưới dạng mã chế độ nghiêm ngặt nếu nó bắt đầu bằng chỉ thị "use strict".)

Hỗ trợ chế độ nghiêm ngặt gần như chưa hoàn thành trong Firefox nightlies mới nhất, do đó có thể tải xuống một lần để phát xung quanh với những phần của chế độ nghiêm ngặt được thực hiện. Tôi vẫn muốn nói ngừng sử dụng sản xuất cho đến khi nó hoàn thành, nhưng nó chắc chắn đã sẵn sàng để thử nghiệm (miễn là bạn hiểu chế độ nghiêm ngặt chưa hoàn toàn được nêu ra). (Đối với liên kết của Sean McMillan, hãy lưu ý rằng các tuyên bố của nó về "hỗ trợ" thể hiện mức tối thiểu cực đại của chức năng cần thiết cho mỗi viên đạn.)

+4

'Nghiêm ngặt hoàn toàn không "chảy máu" - Điều này không hoàn toàn chính xác. Bạn không thể sử dụng '.caller' trong mã không nghiêm ngặt khi hàm bạn sử dụng được xác định ở chế độ nghiêm ngặt. Vì vậy, mã không nghiêm ngặt có thể trong thực tế phá vỡ vì các mã khác đang ở chế độ nghiêm ngặt - tôi muốn xem xét việc chảy máu. – AndreKR

+1

Cách câu hỏi ban đầu được diễn giải, tôi giải thích "chảy máu" có nghĩa là ý nghĩa mã nguồn văn bản, từ ngữ - của kịch bản B chọn độ nghiêm ngặt từ tập lệnh A, mà không B chọn độ chính xác. Rõ ràng, các hiệu ứng của một kịch bản (bao gồm cả các hiệu ứng gây ra bởi độ nghiêm ngặt) được hiển thị - "chảy máu", bạn có thể nói - trong các kịch bản khác.Bản chất * của hiệu ứng có thể khác nhau tùy thuộc vào độ nghiêm ngặt của tập lệnh kích hoạt. Nhưng nghiêm ngặt hay không, hiệu ứng của một kịch bản có thể nhìn thấy được trong kịch bản khác. Đó không phải là một định nghĩa đặc biệt hữu ích về "chảy máu" đối với tôi. –

0
eval(somecodesnippet); // disallowed by "use strict" 

Không nếu bạn khai báo somecodesnippet trước đó.

var somecodesnippet = "your awesome codesnippet here";

eval (somecodesnippet); // KHÔNG cấm bằng cách "sử dụng nghiêm ngặt"

0

Toàn bộ file:

<script...> 
    "use strict"; 

hoặc

Toàn bộ chức năng và chức năng của nó embeded ví dụ:

function fn(){ 
    "use strict"; 
+0

Đã có một câu trả lời được chấp nhận, giải quyết vấn đề OP. Bạn không thêm bất kỳ chất lượng nào nữa. –

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