Trước hết, tôi muốn làm rõ, tôi biết rằng withbị phản đối , và sử dụng nó là chung một thực tế xấu .
Tuy nhiên, câu hỏi của tôi là về một trường hợp đặc biệt: sử dụng một Proxyđối tượng đặc biệt làm tham số của with.
Lý lịch
Tôi đang làm việc trên một dự án, nơi tôi phải giới hạn quyền truy cập của một đoạn mã vào phạm vi toàn cầu.
Một cách tiếp cận có thể là sử dụng một vòng lặp với eval, tạo ra các biến không đổi với giá trị của undefinedtừng thuộc tính của đối tượng toàn cầu, nhưng điều đó dường như còn tồi tệ hơn việc sử dụng withvà không thể giới hạn quyền truy cập vào các biến được tạo bằng letvà const.
Ý tưởng
Ý tưởng là sử dụng một Proxyđối số của with...
hasbẫy luôn quay trở lạitrue, do đó nó không cho phép bất kỳ tra cứu hoặc bài tập nào vượt ra ngoàiwithtuyên bốgetBẫy hoạt động bình thường, ngoại trừ việc chúng némReferenceErrors khi cố gắng truy cập vào một biến không tồn tại (tức là thuộc tính)setbẫy hoạt động bình thường (hoặc có thể chứa một số logic tùy chỉnh)targetđối tượng không có[[Prototype]](tức là nó được tạo bằngObject.create(null))targetđối tượng có một thuộc@@unscopablestính, với giá trị của một đối tượng trống, để cho phép phạm vi của mọi thuộc tính
Vì vậy, một cái gì đó giống như mã này:
const scope = Object.create(null)
Object.assign(scope, {
undefined,
console,
String,
Number,
Boolean,
Array,
Object,
/* etc. */
[Symbol.unscopables]: Object.create(null)
})
const scopeProxy = new Proxy(scope, {
get: (obj, prop) => {
if (prop in obj)
return obj[prop]
else
throw new ReferenceError(`${prop} is not defined`)
},
set: Reflect.set,
has: () => true
})
with(scopeProxy) {
//Sandboxed code
foo = Number('42')
console.log(foo) //42
try{
console.log(scopeProxy) //Inaccessible
}catch(e){
console.error(e) //ReferenceError: scopeProxy is not defined
}
}
Tránh các cơn co thắt
Có một số điều khoản được liệt kê trên trang của MDN về withtuyên bố , nhưng cách sử dụng này được loại bỏ.
1. Hiệu suất
Vấn đề:
Tra cứu các định danh không phải là thành viên của
withđối tượng tham số của câu lệnh là ít hiệu suất hơn.Tránh:
Không có tra cứu có thể vượt ra ngoài đối tượng tham số.
2. Sự mơ hồ
Vấn đề:
Thật khó để quyết định, định danh nào được tra cứu từ những người có cùng tên.
Tránh:
Tất cả các tra cứu và bài tập lấy hoặc sửa đổi thuộc tính của đối tượng tham số.
3. Tương thích chuyển tiếp
Vấn đề:
Các thuộc tính của các đối tượng tham số hoặc nguyên mẫu của chúng có thể thay đổi trong tương lai.
Tránh:
Đối tượng tham số ban đầu trống và không có nguyên mẫu, do đó không có thuộc tính nào có thể thay đổi.
Câu hỏi
Đoạn mã trên hoạt động hoàn hảo và các điều khoản được liệt kê trên MDN không áp dụng cho điều này.
Vì vậy, câu hỏi của tôi là:
Nó vẫn là một thực hành xấu để sử dụng withtuyên bố, và nếu vậy, những nhược điểm của việc sử dụng nó trong trường hợp này là gì?
withnày có tệ hay không.
withvà một proxy vẫn còn khá chậm. Tôi sẽ cố gắng tìm kiếm một giải pháp khác cho vấn đề tiềm ẩn, nhưng khác hơn là bạn chỉ đang sử dụng withnhư một công cụ dường như để làm những gì bạn cần.