2017-07-17 29 views
8

Tôi đang đọc một cuốn sách tuyệt vời có tên "Bí mật của Ninja JavaScript" được viết bởi John Resig & Gấu Bibeaoult. Trong chương 3.2, nó đưa ra một ví dụ;Tại sao các hàm ẩn danh trong javascript có tên?

var canFly = function(){ return true; }; 

Sau đó, nó nói;

Chức năng ẩn danh được tạo và gán cho biến toàn cầu có tên canFly. Do tính chất chức năng của JavaScript, hàm có thể được gọi thông qua tham chiếu này là canFly(). Về mặt này, nó gần như tương đương với chức năng để khai báo một hàm có tên là "canFly", nhưng không hoàn toàn. Một khác biệt lớn là thuộc tính tên của hàm là "", không phải là "canFly".

Nhưng khi tôi cố gắng thực hiện các ví dụ về Công cụ nhà phát triển Chrome và kiểm tra việc name tài sản của canFly chức năng, nó sẽ trả về giá trị "canFly" thay vì một chuỗi rỗng.

canFly.name; 
// > "canFly" 

Các chức năng ẩn danh được gán cho biến không có tên trong những ngày trước đó? Nếu vậy, điều gì đã thay đổi? Hoặc các tác giả có mắc sai lầm không?

+1

Tôi không thể nhớ nơi tôi đọc nó nhưng tôi nhớ đọc rằng trong phiên bản mới của Node/V8 ngay cả chức năng ẩn danh khi được gán cho một biến sẽ nhận được tên biến. Sẽ đăng câu trả lời khi tôi tìm thấy một liên kết. – Aron

+9

[* Tên chức năng suy luận *: Các biến và phương thức có thể suy ra tên của hàm ẩn danh từ vị trí cú pháp của nó (mới trong ECMAScript 2015)] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Tham khảo/Global_Objects/Chức năng/tên # Inferred_function_names) –

+1

Hiện chúng tôi đi. Cảm ơn @AlexK. – Aron

Trả lời

2

Trong lý thuyết chức năng ẩn danh là không bình thường, có nghĩa là không tên. Đây là cách nó được thực hiện ban đầu và trong hơn mười năm mọi người đều ổn với điều này.

Sau đó, hai điều đã xảy ra: toàn bộ chuyển động Web2.0/ajax nơi mọi người bắt đầu triển khai các tính năng giao diện người dùng thường thấy trên ứng dụng dành cho máy tính để bàn trong các trang web và node.js. Hai sự kết hợp này buộc nhiều nhà phát triển phải đối xử với javascript như một ngôn ngữ nghiêm túc và một khi mọi người cảm thấy thoải mái với javascript, họ bắt đầu viết những mã nguồn thực sự lớn.

Điều này dẫn đến khiếu nại về khả năng gỡ lỗi của javascript. Có rất nhiều từ không có bất kỳ trình gỡ rối hữu ích nào (dẫn chúng ta đến các trình gỡ lỗi thực sự tốt trong các trình duyệt mà theo ý kiến ​​của tôi tốt nhất chỉ dành cho MS Visual Studio). .

Điều này đã dẫn đến trình duyệt và các nhà phát triển động cơ js triển khai mã cố gắng đoán "tên" của các chức năng không tên. Theo lý thuyết, tính năng này sai vì bạn không thể luôn đảm bảo rằng tên bạn đoán là cách hàm được gọi (ví dụ: nếu hàm được gán cho một số biến khác nhau). Trong thực tế một cái gì đó mà làm việc 90% thời gian là tốt hơn so với không có gì cả.

+1

Cuốn sách thú vị của John Resig đã được xuất bản vào năm 2008 để cho chúng ta một thời gian khắc nghiệt giữa năm 2008 và 2017 khi tính năng này được triển khai lần đầu tiên. Tôi tin rằng nếu bạn thực sự tò mò, bạn có thể tìm hiểu mã nguồn của các công cụ js khác nhau cho các cam kết mã. Javascript của Apple (nitro), v8 của Google và chakracore của Microsoft đều là mã nguồn mở. – slebetman

+0

Cảm ơn rất nhiều! Có vẻ như tôi cần phải học C/C++ để hiểu mã nguồn của các công cụ trình duyệt nhưng, tôi nghĩ, phải hiểu rõ hơn về câu trả lời cho câu hỏi của tôi và cách JS thực sự làm việc đằng sau hậu trường. –

1

Dưới đây là một phiên bản hơi tinh chỉnh mã thử nghiệm của bạn cung cấp cho một đầu mối rằng .name có thể chỉ được cố gắng thực sự khó khăn để thể hữu ích:

var canFly = function() {}; 
 
var areYouSure = function yesIAm(){}; 
 
console.log(canFly.name); 
 
console.log(areYouSure.name); 
 
console.log((function(){}).name);

Kiểm tra để biết chi tiết tại MDN chúng ta có thể thấy nó đã từng là tài sản phi tiêu chuẩn:

Tài sản function.name trả về tên hàm.

...mà nhường nó vào ES2015 (tôi nhấn mạnh):

biến và phương pháp có thể suy ra tên của một chức năng ẩn danh từ vị trí cú pháp của nó (mới trong ECMAScript 2015).

Vì vậy, nó trả về tên nhưng khi không thể, nó sẽ cố gắng đoán.

+0

Cảm ơn! Điều này có nghĩa là các hàm ẩn danh chỉ có thuộc tính 'name' trống nếu chúng chưa gán cho một biến. –

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