Sự khác biệt giữa shim và polyfill là gì?


406

Cả hai dường như được sử dụng trong các vòng tròn phát triển web, xem ví dụ: HTML5 Cross Browser Polyfills , cho biết:

Vì vậy, ở đây chúng tôi đang thu thập tất cả các miếng chêm, dự phòng và polyfill ...

Hoặc, có dự án es5-shim .

Trong dự án hiện tại của tôi, chúng tôi đang sử dụng một số trong số này và tôi muốn dán tất cả chúng vào cùng một thư mục. Vậy, tôi nên gọi thư mục này là gì --- shimshay polyfills?


6
mở lại: Tôi cho rằng "tôi nên gọi thư mục này là gì" có thể dựa trên quan điểm, nhưng nó thực sự không được đưa ra bối cảnh lớn hơn của câu hỏi - đó cũng không phải là khía cạnh quan trọng nhất của câu hỏi này. Tất cả các câu trả lời ở đây dường như là thỏa thuận, và có sự sử dụng đáng kể các sự kiện, tài liệu tham khảo và chuyên môn cụ thể.
tộc

Câu trả lời:


386
  • Một shim là bất kỳ đoạn mã mà thực hiện đánh chặn cuộc gọi API và cung cấp một lớp trừu tượng. Nó không nhất thiết bị giới hạn trong một ứng dụng web hoặc HTML5 / CSS3.

  • Một polyfill là một loại shim mà các trình duyệt retrofits di sản với HTML5 hiện đại / CSS3 các tính năng thường sử dụng Javascript hoặc Flash.

Trả lời câu hỏi cụ thể của bạn, gọi thư mục của bạn shimsnếu bạn muốn giữ thư mục chung chung.


234

Shim

Nếu bạn đã quen thuộc với mẫu bộ điều hợp, thì bạn sẽ biết shim là gì. Shims chặn các lệnh gọi API và tạo một lớp trừu tượng giữa người gọi và mục tiêu. Thông thường các miếng chêm được sử dụng cho khả năng tương thích ngược. Chẳng hạn, gói es5-shim npm sẽ cho phép bạn viết cú pháp ECMAScript 5 (ES5) và không quan tâm xem trình duyệt có chạy ES5 hay không. Lấy Date.now làm ví dụ. Đây là một hàm mới trong ES5 trong đó cú pháp trong ES3 sẽ là Date (). GetTime () mới . Nếu bạn sử dụng es5-shim, bạn có thể viết Date.now và nếu trình duyệt bạn đang chạy hỗ trợ ES5, nó sẽ chỉ chạy. Tuy nhiên, nếu trình duyệt đang chạy, công cụ ES3 es5-shim sẽ chặn cuộc gọi đến Date.nowvà chỉ trả về Ngày mới (). getTime () thay vào đó. Sự đánh chặn này được gọi là shinkle. Mã nguồn có liên quan từ es5-shim trông như thế này:

if (!Date.now) {
    Date.now = function now() {
        return new Date().getTime();
    };
}

Polyfill

Polyfilling thực sự chỉ là một phiên bản chuyên biệt của shinkle. Polyfill là về việc triển khai các tính năng bị thiếu trong API, trong khi đó, shim sẽ không nhất thiết phải thực hiện nhiều tính năng bị thiếu cũng như về việc sửa các tính năng. Tôi biết những điều này có vẻ quá mơ hồ, nhưng trong đó các miếng chêm được sử dụng như một thuật ngữ rộng hơn, polyfill được sử dụng để mô tả các miếng chêm cung cấp khả năng tương thích ngược cho các trình duyệt cũ hơn. Vì vậy, trong khi các miếng chêm được sử dụng để che đậy những tội lỗi cũ, polyfill được sử dụng để mang lại những cải tiến trong tương lai. Như một ví dụ không có sự hỗ trợ cho sessionStorage trong IE7, nhưng polyfill trong sessionstorage gói NPM sẽ bổ sung thêm tính năng này trong IE7 (trở lên) bằng cách sử dụng các kỹ thuật như lưu trữ dữ liệu trong tên thuộc tính của cửa sổ hoặc bằng cách sử dụng các tập tin cookie.


107
Vì vậy, trong khi các miếng chêm được sử dụng để che đậy những tội lỗi cũ, polyfill được sử dụng để mang lại những cải tiến trong tương lai. Điều này tổng hợp tất cả mọi thứ với tôi. Cảm ơn bạn đã giải thích rõ ràng.
JohnnyQ 8/11/2015

Câu trả lời này rất hữu ích, cảm ơn. Nhưng dường như hai thuật ngữ này thường không được sử dụng chính xác trên web, bao gồm es5-shim. Tôi nghĩ es5-shim là sự pha trộn giữa shims và polyfill theo định nghĩa của bạn.
Matt Browne

WOW -> Vì vậy, trong khi các miếng chêm được sử dụng để che đậy những tội lỗi cũ, polyfill được sử dụng để mang lại những cải tiến trong tương lai. <- Rất cám ơn!
zeppelin

3
Ví dụ ngày trông giống như một Polyfill đối với tôi. Tại sao tôi nghĩ rằng đó là một Polyfill? Bởi vì Date.now là một cuộc gọi bản địa. Một Polyfill sẽ thêm tính năng đó với cùng một API liền mạch vào Trình duyệt. Một shim đi kèm với một API mới như: MyShim.Date.now(); Vui lòng sửa cho tôi nếu tôi sai.
TatzyXY

99

Từ những gì tôi hiểu:

Một polyfill là mã phát hiện nếu một API "dự kiến" nào đó bị thiếu và thực hiện thủ công. Ví dụ

if (!Function.prototype.bind) { Function.prototype.bind = ...; }

Một shim là mã chặn các lệnh gọi API hiện có và thực hiện các hành vi khác nhau. Ý tưởng ở đây là bình thường hóa một số API nhất định trên các môi trường khác nhau. Vì vậy, nếu hai trình duyệt triển khai cùng một API khác nhau, bạn có thể chặn các lệnh gọi API trong một trong các trình duyệt đó và thực hiện hành vi của nó phù hợp với trình duyệt khác. Hoặc, nếu trình duyệt có lỗi trong một trong các API của nó, bạn có thể chặn các cuộc gọi đến API đó một lần nữa và sau đó tránh lỗi.


66

Trích dẫn Axel Rauschmayer từ cuốn sách Nói JavaScript :

  • Shim là một thư viện mang API mới đến môi trường cũ hơn, chỉ sử dụng các phương tiện của môi trường đó.
  • Một polyfill là một shim cho API trình duyệt. Nó thường kiểm tra xem trình duyệt có hỗ trợ API không. Nếu không, polyfill sẽ tự cài đặt. Điều đó cho phép bạn sử dụng API trong cả hai trường hợp. Thuật ngữ polyfill xuất phát từ một sản phẩm cải tiến nhà; theo Remy Sharp :

    Polyfilla là một sản phẩm của Vương quốc Anh được gọi là Spackling Paste ở Mỹ. Với ý nghĩ đó: hãy nghĩ về các trình duyệt như một bức tường với những vết nứt trong đó. Các [polyfill] này giúp làm phẳng các vết nứt và cung cấp cho chúng tôi một tường trình duyệt mượt mà đẹp để làm việc.


9

Shim. Shim là một thư viện mang API mới đến môi trường cũ hơn, chỉ sử dụng các phương tiện của môi trường đó.

Polyfill. Vào tháng 10 năm 2010, Remy Sharp đã viết blog về thuật ngữ này có tên là Polyfill [[qua Rick Waldron]:

Polyfill là một đoạn mã (hoặc plugin) cung cấp công nghệ mà bạn, nhà phát triển, mong muốn trình duyệt cung cấp nguyên bản. Làm phẳng cảnh quan API nếu bạn muốn.


8

Một bài viết tuyệt vời viết về điều này từ một vài năm trước đã giải thích điều này tốt:

Polyfill là gì?

Trong bài viết, (2) chỉ đơn giản là tương phản như vậy:

Shim: một đoạn mã mà bạn có thể thêm (tức là JavaScript) sẽ sửa một số chức năng, nhưng nó thường có API riêng .

Polyfill: một cái gì đó bạn có thể thả vào (tức là JavaScript) và nó sẽ âm thầm hoạt động để bắt chước các API trình duyệt hiện có mà không được hỗ trợ.


1
Tôi nghĩ rằng đây là một đại diện sai lệch về cả cách sử dụng phổ biến và những gì Remy Sharp thực sự nói trong bài đăng trên blog mà bạn đã liên kết. Shim thường được sử dụng đồng nghĩa với polyfill hiện nay (đặc biệt là es5-shimes6-shim ) và Remy đặc biệt nói về từ đó với từ 'shim' ám chỉ API tùy chỉnh (so sánh với shim.gif). Anh ta rất không cho rằng các từ được sử dụng theo cách này và bằng cách nói "với tôi" , anh ta ngầm thừa nhận rằng việc sử dụng của anh ta không phải là phổ quát.
Đánh dấu Amery
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.