Tại sao các khung / thư viện JavaScript có các hàm đã tồn tại trong JavaScript thuần?


60

Tôi tự hỏi tại sao các khung / thư viện có người trợ giúp riêng của họ mặc dù chúng tồn tại nguyên bản.

Hãy dùng jQueryAngularJS . Chúng có các eachhàm lặp riêng :

Nhưng chúng ta có Array.prototype.forEach.

Tương tự như vậy,

Nhưng chúng tôi có JSON.parse()chức năng trong vanilla JavaScript.


75
Là một người nhớ lại những ngày xưa tồi tệ của sự phát triển web, câu hỏi này khiến tôi khóc.
josh3736

3
@ josh3736 Ít nhất bạn vẫn không phải hỗ trợ IE6 ('may, chỉ may mắn theo cách "làm cho nó hoạt động, nó có thể trông giống như tào lao")
Izkata

12
jQuery.eachArray.prototype.forEachkhông tương đương.
zzzzBov

3
Những gì bạn nên tự hỏi mình là: bao nhiêu chức năng được tìm thấy trong vanillaJS bây giờ, có nguồn gốc từ các bộ công cụ như jQ và tương tự? Câu trả lời là: nhiều . Điều này không đặt ra câu hỏi: tại sao chúng ta vẫn sử dụng chúng? Tại sao bao gồm jQuery $.eachvà không sử dụng bản gốc (và nhanh hơn) Array.prototype.forEach?
Elias Van Ootegem

1
@ josh3736 Không sao đâu anh bạn ... i.stack.imgur.com/HJs4V.jpg
Crono

Câu trả lời:


93

Bởi vì khi các thư viện đó được viết, một số trình duyệt chính không hỗ trợ các tính năng đó. Sau khi được viết và sử dụng, các tính năng này không thể bị xóa khỏi các thư viện này mà không phá vỡ nhiều ứng dụng.

(Trong trường hợp này, "trình duyệt chính" có nghĩa là trình duyệt vẫn chiếm thị phần lớn, bao gồm các phiên bản trình duyệt cũ hơn như Internet Explorer, nơi số lượng lớn người dùng không nhất thiết phải nâng cấp lên phiên bản mới nhất.)


44
$ ('marquee'). Each (function () {$ (this) .append ($ ('<bssound />', {src: "good-answer.mp3"}));});
Pierre Arlaud

36
@dirkk Không phải các trình duyệt gần đây không hỗ trợ nó. Không phải ai cũng may mắn có được khán giả sử dụng trình duyệt gần đây.
George Reith

14
Array.prototype.forEachLặp lại chỉ trên các mảng - cả hai hàm lặp của thư viện có thể lặp lại trên các mảng hoặc đối tượng.
JoeG

3
Các chức năng có sẵn để hỗ trợ các trình duyệt cũ và hỗ trợ mã cũ gọi thư viện và lập trình viên không muốn viết lại. Ngay cả khi bạn đã bỏ hỗ trợ cho IE 6, bạn vẫn có thể sử dụng một số JavaScript được viết khi bạn cần hỗ trợ các bản sao IE cổ.
Michael Storesin

6
Nhiều hàm này (ví dụ: jQuery.parseJSON ()) chỉ kiểm tra xem trình duyệt có hỗ trợ hay không và sau đó tự đặt phương thức trình duyệt và chỉ sử dụng một thay thế trên các trình duyệt không tương thích!
Josef

35

Bởi vì các trình duyệt khác nhau có các triển khai và tính năng khác nhau được nướng trong công cụ JavaScript của chúng. Mã "vanilla-JS" giống nhau có thể chạy khác nhau trên hai trình duyệt khác nhau hoặc thậm chí hai phiên bản khác nhau của cùng một trình duyệt.

Lớp trừu tượng được cung cấp bởi các thư viện JS phổ biến là một cách xoay quanh vấn đề này. Đằng sau, nó hoạt động xung quanh các khả năng và giới hạn của các trình duyệt khác nhau và cung cấp một API thống nhất, dễ sử dụng trên đầu trang. Đến lượt mình, điều này cho phép các hoạt động phổ biến như lấy một đối tượng DOM hoặc tìm nạp dữ liệu JSON là nhất quán, hiệu quả và không tin vào trình duyệt.

Điều này làm cho cuộc sống dễ dàng hơn rất nhiều đối với các nhà phát triển hiện có thể tập trung vào mã nào nên làm, thay vì cách viết mã để làm việc với trình duyệt X hoặc Y.


2
Hành vi của "lõi JS" được chỉ định rõ và được thử nghiệm trên tất cả các trình duyệt.
Domenic

2
@Domenic Cú pháp sang một bên, việc triển khai javascript khác với trình duyệt. Có các thuộc tính, phương thức, sự kiện và tính năng bạn sẽ tìm thấy chỉ trong một vài trình duyệt, hoặc thậm chí chỉ trong một đôi khi.
Crono

1
Có, trình duyệt có các tính năng không chuẩn. Điều đó không có gì để làm với các tính năng tiêu chuẩn được thảo luận trong câu hỏi này.
Domenic

8
@Domenic Nếu theo "các tính năng tiêu chuẩn được thảo luận trong câu hỏi", bạn có nghĩa là Array.prototype.forEachvà các JSON.parsechức năng, một tìm kiếm nhanh trên Google sẽ cho bạn thấy rằng bạn đã sai. JSONđối tượng không được hỗ trợ trên IE7 và forEachkhông được xác định trên một số phiên bản Opera. Các thư viện như jQuery tuy nhiên đã biết về những hạn chế này và làm việc xung quanh chúng đằng sau hậu trường. Vì vậy, tôi nghĩ rằng câu trả lời của tôi không đứng.
Crono

27

1. Tương thích ngược

JavaScript là một triển khai của ECMAScript . Hầu hết các chức năng đó được giới thiệu trong ECMAScript 5 (ES5) tuy nhiên nhiều trình duyệt cũ hơn vẫn có thị phần đủ đáng kể không hỗ trợ các chức năng này (xem bảng tương thích ECMAScript 5 ), đáng chú ý nhất trong số này là IE8.

Nói chung, các thư viện sẽ trở lại triển khai gốc nếu nó tồn tại nếu không sử dụng polyfill của riêng họ, ví dụ: hãy xem triển khai của AngularJS ( angular.js L203-257 ):

function forEach(obj, iterator, context) {
  var key;
  if (obj) {
    if (isFunction(obj)){
      for (key in obj) {
        // Need to check if hasOwnProperty exists,
        // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
        if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
          iterator.call(context, obj[key], key);
        }
      }
    } else if (obj.forEach && obj.forEach !== forEach) {
      obj.forEach(iterator, context);
    } else if (isArrayLike(obj)) {
      for (key = 0; key < obj.length; key++)
        iterator.call(context, obj[key], key);
    } else {
      for (key in obj) {
        if (obj.hasOwnProperty(key)) {
          iterator.call(context, obj[key], key);
        }
      }
    }
  }
  return obj;
}

Các dòng sau kiểm tra xem forEachphương thức có tồn tại trên đối tượng hay không và đó có phải là phiên bản AngularJS hay không. Nếu không, nó sử dụng chức năng đã được chỉ định (phiên bản gốc):

} else if (obj.forEach && obj.forEach !== forEach) {
  obj.forEach(iterator, context);
}

2. Thuận tiện

Trong JavaScript nguyên gốc Array.prototype.forEachlà một phương thức dành riêng cho một thể hiện của Array, tuy nhiên hầu hết mọi thứ Objectđều có thể lặp lại được.

Vì lý do này, nhiều người tạo thư viện làm cho chức năng của họ đa hình (có thể chấp nhận nhiều loại làm đầu vào). Hãy lấy mã AngularJS ở trên và xem những gì đầu vào chấp nhận:

Chức năng :

if (isFunction(obj)){
  for (key in obj) {
    // Need to check if hasOwnProperty exists,
    // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
    if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
      iterator.call(context, obj[key], key);
    }
  }

Mảng (với sự hỗ trợ forEach bản địa):

} else if (obj.forEach && obj.forEach !== forEach) {
  obj.forEach(iterator, context);

Các đối tượng giống như mảng bao gồm Mảng (không có hỗ trợ forEach gốc), Chuỗi, HTMLE bổ sung, Đối tượng có thuộc tính độ dài hợp lệ:

} else if (isArrayLike(obj)) {
  for (key = 0; key < obj.length; key++)
    iterator.call(context, obj[key], key);

Các đối tượng:

} else {
  for (key in obj) {
    if (obj.hasOwnProperty(key)) {
      iterator.call(context, obj[key], key);
    }
  }
}

Phần kết luận

Như bạn có thể thấy AngularJS sẽ lặp lại trên hầu hết mọi Đối tượng JavaScript, mặc dù nó hoạt động giống như chức năng gốc, nó chấp nhận nhiều loại đầu vào khác nhau và do đó là một bổ sung hợp lệ cho thư viện cũng như cách mang các hàm ES5 để các trình duyệt cũ.


2
Bạn có thể muốn cập nhật liên kết của mình để trỏ đến một cam kết cụ thể (ví dụ: angular.js L203-257 ) để tham khảo trong tương lai sau khi masterthay đổi.
Whymarrh
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.