1. Trang chủ
  2. » Luận Văn - Báo Cáo

You don''t know JS (Tiếng Việt) — Khởi đầu - Chương 1: Hiểu về lập trình

249 3 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 249
Dung lượng 1,34 MB

Nội dung

You don''t know JS (Tiếng Việt) — Khởi đầu - Chương 1: Hiểu về lập trình

You don't know JS (Tiếng Việt) — Khởi đầu - Chương 1: Hiểu lập trình Q trình dịch khơng tránh sai sót, bạn có phát xin phản hồi giúp tơi, khơng kệ ln :)) Tơi biết ban đầu có đoạn dịch lủng củng, hứa dịch ngày dễ đọc Code Một chương trình, thường gọi source code​ code​, tập hợp hướng dẫn để yêu cầu máy tính cần xử lý nhiệm vụ Thơng thường, code lưu dạng file văn bản, với js bạn gõ code trực tiếp lên console trình duyệt Các nguyên tắc định dạng hợp lệ kết hợp hướng dẫn gọi ngơn ngữ máy tính, hay cịn gọi cú pháp, tương tự ngôn ngữ giao tiếp cho bạn cách đọc từ tạo câu cách sử dụng từ dấu câu Các câu lệnh (Statements) Trong ngơn ngữ máy tính, nhóm từ, số, cách thức thực thi nhiệm vụ cụ thể gọi câu lệnh Trong JS, câu lệnh sau: a = b * 2; Ký tự a​ ​b​ ​biến (variable), giống hộp, bạn lưu trữ đồ vật Trong lập trình, biến giữ giá trị (ví dụ số 42​) chương trình sử dụng Về mặt tương phản, số 2​ thân giá trị, gọi giá trị ký tự (literal value), độc lập khơng lưu trữ biến Dấu =​ ​*​ ​tốn tử (operators) (xem "Tốn tử") thực thi hành động với giá trị biến phân cơng phép tốn nhân Hầu hết câu lệnh JS kết thúc dấu chấm phẩy (;​) cuối câu Lệnh a = b * 2;​ báo cho máy tính giá trị lưu trữ biến b​, nhân giá trị với 2, sau lưu kết lại vào biến khác gọi a​ Lập trình tương tự sưu tập nhiều câu lệnh mô tả tất bước để thực thi mục đích lập trình Biểu thức (Expressions) Các câu lệnh tạo thành từ hay nhiều biểu thức Một biểu thức tham chiếu biến giá trị, tập hợp giá trị biến kết hợp thành tốn tử Ví dụ: a = b * 2; Câu lệnh có biểu thức bên nó: ● 2​ ​giá trị biểu thức trực kiện ● b​ g ​ iá trị biểu thức, có nghĩa lấy giá trị ● b * 2​ ● a = b * 2​ ​biểu thức toán học, nghĩa làm phép nhân biểu thức gán, nghĩa gán kết biểu thức b * 2​ cho biến a​ (cịn tìm hiểu thêm sau) Một biểu thức chung đứng cịn gọi lệnh biểu thức(expression statement), ví dụ sau: b * 2; Kiểu biểu thức thường khơng hữu dụng, chẳng có tác dụng chương trình chạy — nó lấy giá trị b​ nhân với 2​, sau khơng làm với kết Một loại câu lệnh biểu thức biểu thức lệnh gọi (call expression) (Xem “Functions”), toàn câu lệnh hàm tự gọi biểu thức: alert( a ); Thực thi chương trình Làm cách mà tập hợp câu lệnh lập trình u cầu máy tính phải làm gì? Chương trình cần thực thi, hay cịn biết đến với tên chạy chương trình Các lệnh giống a = b * 2​ hữu dụng cho lập trình viên đọc viết, khơng hồn tồn dạng để máy tính hiểu trực tiếp Vì vậy, trình tiện ích đặc biệt máy tính (hoặc thơng dịch-interpreter biên dịch-compiler ) sử dụng để dịch code bạn viết thành lệnh mà máy tính hiểu Đối với số ngơn ngữ máy tính, chương trình chạy dịch câu lệnh thường hồn thành từ xuống dưới, dịng một, thường gọi thông dịch mã Một số ngôn ngữ khác, dịch hoàn thiện trước, gọi biên dịch mã, sau chương trình chạy, chạy biên dịch xong máy sẵn sàng chạy JavaScript thường khẳng định ngơn ngữ thơng dịch, mã nguồn JavaScript xử lý lần chạy Nhưng điều khơng hồn tồn xác, thực JavaScript engine biên dịch chương trình sau chạy mã biên dịch Ghi chú: thông tin thêm biên dịch JavaScript, xem chương đầu Phạm vi & Đóng kín seri Tự luyện Chương giới thiệu khái niệm lập trình với mẫu code đơn giản, tất viết JavaScript (đương nhiên!!!) Bạn cần luyện tập khái niệm cách tự gõ code Các dễ mở developer tool console trình duyệt Mẹo: Thường bạn mở developer console với phím tắt từ menu Thông tin chi tiết việc mở sử dụng console trình duyệt ưa thích bạn, xem “Mastering The Developer Tools Console”​ Để gõ nhiều dòng console lúc, sử dụng + ​ để chuyển sang dòng Khi bạn nhấn ​, console chạy tất bạn vừa viết Hãy làm quen với việc chạy code console Trước tiên, đề nghị bạn mở tab trống trình duyệt Tơi thích làm cách việc gõ about:blank​ địa Sau cần chắn developer console mở đề cập Và gõ code xem chúng chạy: a = 21; b = a * 2; console.log( b ); Gõ đoạn code trước Chrome console tạo như: Hãy thử đi, cách học code hay để bắt đầu học lập trình đó! Output Trong mẫu code trên, sử dụng console.log( )​ Tóm lại, nhìn vào dịng code xem Bạn đốn, xác có thẻ print text (tức ouput​ cho người dùng) dev console Có hai đặc tính mà cần giải thích Đầu tiên, phần log( b )​ đại diện việc gọi hàm (xem "Functions") Những xảy giao biến b​ cho hàm đó, hàm yêu cầu lấy giá trị b​ print lên console Thứ hai, phần console.​ làm object tham chiếu nơi có hàm​log( )​ Chúng ta xem object thuộc tính chi tiết Chương Cách khác để tạo output để bạn nhìn chạy alert( )​ Ví dụ: alert( b ); Nếu bạn chạy nó, bạn thấy thay hiển thị output lên console, hiển thị popup “OK” với nội dung biến b​ Tuy nhiên, sử dụng console.log( )​ giúp cho việc học bạn thuận tiện nhiều so với alert( )​, bạn output nhiều giá trị lúc mà khơng bị phiền hà trình duyệt Với sách dùng console.log( ) Input Khi thảo luận output, bạn thắc mắc input​ (ví dụ nhận thơng tin từ người dùng) Cách thông thường trang HTML hiển thị form cho người dùng gõ vào, sau sử dụng js để đọc giá trị vào biến chương trình Nhưng có cách đơn giản để lấy input để học trình bày bạn học theo sách này, sử dụng function prompt( ) age = prompt( "Please tell me your age:" ); console.log( age ); Như bạn đoán, mẩu tin bạn đưa vào prompt( )​ trường hợp này, "Please popup Điều tương tự tell me your age:"​ in lên Khi bạn nhập input text cách nhấp “OK”, bạn tuân theo giá trị mà bạn gõ lưu biến age​, mà output​ với console.log( )​: You Don’t Know JS: this & Nguyên mẫu đối tượng — Chương 1: this That? Một chế hãi hùng JavaScript từ khoá ​this​ Nó từ khố nhận dạng đặc biệt tự động xác định scope hàm, lập trình viên JavaScript dày dặn phải điêu đứng với câu chuyện xác Công nghệ tiên tiến với phép thuật không phân biệt được. — Arthur C Clarke Cơ chế this​ không hẳn ghê gớm câu trên, lập trình viên thường diễn giải tâm trí cách thêm từ "phức tạp" "mơ hồ", this​ xem huyền diệu hoang mang   Tại lại this? Nếu chế this​ phức tạp nên lập trình viên JavaScript dày dạn thắc mắc lại hữu dụng? Hay đem lại rắc rối? Trước tìm hiểu nào​, nên xác định Hãy thử minh hoạ động lực tiện ích this​: function identify() { return this.name.toUpperCase(); } function speak() { var greeting = "Hello, I'm " + identify.call( this ); console.log( greeting ); } var me = { name: "Kyle" }; var you = { name: "Reader" }; identify.call( me ); // KYLE identify.call( you ); // READER speak.call( me ); // Hello, I'm KYLE speak.call( you ); // Hello, I'm READER Nếu đoạn code làm bạn bối rối, đừng lo! Chúng ta tìm hiểu cụ thể sau Chỉ cần đặt câu hỏi qua bên, ta nhìn rõ sao​ Đoạn trích cho phép hàm identify()​ ​speak()​ tái sử dụng cho object nhiều ngữ cảnh (​me​ ​you​) thay sử dụng nhiều phiên khác hàm cho object Thay sử dụng this​, bạn thơng qua object cách rõ ràng ngữ cảnh cho identify()​ ​speak()​ function identify(context) { return context.name.toUpperCase(); } function speak(context) { var greeting = "Hello, I'm " + identify( context ); console.log( greeting ); } identify( you ); // READER speak( me ); // Hello, I'm KYLE Tuy nhiên, chế this​ cung cấp phương thức tao nhã theo kiểu ngầm truyền đối tượng tham chiếu, hướng tới thiết kế API rõ ràng dễ sử dụng Mô hình bạn sử dụng phức tạp, bạn thấy rõ việc dùng tham số cụ thể tên tuổi thường rối rắm dùng this​ Khi bạn khám phá object & prototype, bạn thấy hữu dụng tập hợp hàm tự động tham chiếu với object ngữ cảnh thích hợp Các nhầm lẫn Chúng ta sớm giải thích this​ ​thực hoạt động sao, trước tiên phải xoá tan hiểu nhầm khơng thực Cái tên “this” tạo số nhầm lẫn lập trình viên cố gắng nghĩ theo nghĩa đen Có hai ý nghĩa thường đưa hai sai Chính Cám dỗ phổ biến giả định thân this​ hàm Ít nhất, suy luận có lý mặt ngữ pháp Tại bạn muốn tham chiếu hàm bên nó? Một số lý phổ biến thứ kiểu đệ quy (gọi hàm từ bên nó) có hàm xử lý kiện (event handler) mà tự huỷ lần gọi Các lập trình viên làm quen với chế JS thường tham chiếu hàm object (vì tất hàm JS object!) cho phép bạn lưu trữ state​ (giá trị bên thuộc tính) gọi hàm Mặc dù điều chắn có số hạn chế sử dụng, phần cịn lại sách mô tả nhiều mô hình khác cho vị trí tốt để lưu trữ state bên cạnh mơ hình object hàm Ở tìm hiểu vấn đề chút, để minh hoạ this khơng cho hàm tham chiếu lên giả định Xem đoạn code đây, thử theo dõi lần hàm ​foo​được gọi: function foo(num) { console.log( "foo: " + num ); // theo dõi lần `foo` gọi this.count++; } foo.count = 0; var i; for (i=0; i 5) { foo( i ); } } // foo: // foo: // foo: // foo: // lần `foo` gọi? console.log( foo.count ); // WTF? foo.count​ 0​, qua bốn lần console.log​ rõ ràng ​foo( )​ kiện gọi bốn lần Sự thất vọng bắt nguồn từ diễn dịch trực nghĩa this​ (​this.count++​) Khi ​foo.count = 0​ thực thi, thực chất thêm thuộc tính count​ vào hàm ​foo​ Nhưng với this.count​tham chiếu hàm, ​this​không trỏ đến hàm chút nào, tên thuộc tính giống nhau, object gốc lại khác nhau, nhầm lẫn xảy Ghi chú​: Một lập trình viên có trách nhiệm phải hỏi chỗ “nếu thêm thuộc tính count​ lại khơng phải mong muốn, count​ mà thêm nào?" Thực tế, đào sâu thêm, bạn thấy vơ tình bạn tạo biến tồn cục count​ (xem Chương để biết xảy nào), có giá trị NaN​ Tất nhiên, bạn nhận thấy kết đặc biệt này, câu ta có câu hỏi tổng quan hơn: "Nó tồn cục nào? lại kết thúc NaN​thay cho giá trị đếm được?" (Xem Chương 2) Thay dừng điểm đào sâu vào lý tham chiếu this​ khơng thoả kỳ vọng, trả lời câu hỏi khó quan trọng này, nhiều lập trình viên đơn giản tránh lỗi này, khám phá giải pháp khác, ví dụ tạo object để giữ giá trị count​: function foo(num) { console.log( "foo: " + num ); // theo dõi `foo` gọi lần data.count++; } var data = { count: }; var i; for (i=0; i 5) { foo( i ); } } // foo: // foo: // foo: // foo: // lần `foo` gọi? console.log( data.count ); // Trong rõ ràng cách tiếp cận “giải quyết” vấn đề, khơng may lại bỏ qua vấn đề thực sự — thiếu hiểu biết ý nghĩa this​ cách làm việc thay vào rút lui vào chế gần gũi hơn: lexical scope Chú ý: Lexical scope chế tốt hững dụng; Trên phương diện tơi khơng coi thường việc sử dụng (Xem “Scope & Closures”​) Nhưng lúc ​đoán​ sử dụng this nào, thường xun hiểu sait​ hì khơng phải lý tốt để chuyển qua sử dụng lexical scope khơng học sao​ ​this​ lẩn tránh bạn Để tham chiếu hàm bên nó, thân this thường khơng đầy đủ, bạn cần có tham chiếu đến hàm thông qua định danh gốc (biến) để trỏ vào Xem hàm đây: function foo() { foo.count = 4; // `foo` tham chiếu đến } setTimeout( function(){ // hàm vơ danh, khơng thể tham chiếu đến }, 10 ); Trong hàm thứ nhất, gọi “hàm định danh”, foo​ tham chiếu sử dụng để tham chiếu đến hàm bên Nhưng ví dụ thứ 2, hàm callback qua setTimeout( ) khơng có nhận dạng tên (cịn gọi "hàm vơ danh"), khơng có cách tham chiếu đến object hàm Ghi chú: Có phương thức cũ bị bãi bỏ arguments.callee tham chiếu bên hàm cũng​ trỏ object hàm hàm thực thi Các tham chiếu thường cách để tiếp cận object hàm vô danh bên Tuy nhiên, cách tiếp cận tốt tránh sử dụng chức ẩn danh hồn tồn, hàm cần tham chiếu nó, thay vào tạo hàm có tên (biểu thức) arguments.callee​không sử dụng sử dụng khơng nên Do giải pháp khác cho ví dụ sử dụng nhận diện foo​như tham chiếu object hàm vị trí, khơng sử dụng this​ nữa, hoạt động function foo(num) { console.log( "foo: " + num ); // Kiểm tra lần `foo` gọi foo.count++; } foo.count = 0; var i; for (i=0; i 5) { foo( i ); } } // foo: // foo: // foo: // foo: // Bao nhiêu lần `foo` gọi? console.log( foo.count ); // Tuy nhiên, cách tiếp cận tương tự bước thực hiểu this​ dựa hoàn toàn vào lexical scope biến foo​ Cách khác để tiếp cận vấn đề buộc this​ thực trỏ vào foo object hàm: function foo(num) { console.log( "foo: " + num ); // theo dõi lần `foo` gọi // Ghi chú: `this` thực `foo`, dựa vào // `foo` gọi (xem bên dưới) this.count++; } foo.count = 0; var i; for (i=0; i 5) { // sử dụng `call( )`, chắn `this` // tự trỏ vào object hàm (`foo`) foo.call( foo, i ); } } // foo: // foo: // foo: // foo: // lần `foo` gọi? console.log( foo.count ); // Thay tránh né ​this​, bao lấy Chúng ta giải thích kỹ thuật hoạt động tốt nào, đừng lo lắng bạn chút băn khoan! Phạm vi (Scope) Quan niệm sai lầm phổ biến ý nghĩa this​ cách đó, tham chiếu đến scope hàm Đây câu hỏi khéo, xét mặt đúng, khía cạnh khác sai Một cách rõ ràng this​ khơng tham chiếu đến lexical scope hàm Đúng xét nội bộ, scope dạng giống object có thuộc tính cho object định danh sẵn có Nhưng scope "object" khơng thể truy cập vào JavaScript code Nó phần bên thực thi Engine.​ Xem đoạn code cố (và thất bại!) vượt qua ranh giới sử dụng this​ để ngầm tham chiếu vào lexical scope hàm: function foo() { var a = 2; this.bar(); } function bar() { console.log( this.a ); } foo(); //undefined Có nhiều sai sót đoạn code Đoạn code bạn thấy trích tách từ đoạn code thực tế trao đổi diễn đàn cộng đồng hỗ trợ Nó minh hoạ tuyệt vời (nếu không đáng buồn) cho việc hiểu sai this​ cho giả định đặt Đầu tiên, cố gắng tạo để tham chiếu hàm bar() thông qua ​this.bar()​ Hầu chắn vơ tình n ​ ó hoạt động, giải thích sao​ sau Cách tự nhiên để gọi bar()​ bỏ qua đầu mối this​ cần tạo tham chiếu lexical đến hàm định danh Tuy nhiên, lập trình viên viết đoạn code cố gắng sử dụng this​ để tạo cầu lexical scope foo()​ ​bar()​, từ bar()​ tiếp cận biến a​ scope foo()​ ​Chẳng có cầu xảy Bạn khơng thể sử dụng this​ để tham chiếu tìm thứ lexical scope Hồn tồn khơng thể Mỗi bạn cảm thấy muốn pha trộn việc tìm kiếm với this​, ln nhớ rằng: khơng có cầu hết this gì? Với giả định sai sót khác nhau, chuyển qua việc ý chế hoạt động thực this​ Chúng ta nhắc this​ ràng buộc author-time mà ràng buộc runtime Nó dựa ngữ cảnh điều kiện gọi hàm Ràng buộc this​ không liên quan với nơi mà hàm khai báo, thay vào đó, thứ liên quan đến cách gọi hàm Khi hàm gọi ra, ghi kích hoạt hay cịn gọi ngữ cảnh thực thi tạo Bản ghi chứa thông tin nơi mà hàm gọi (call-stack), cách​ hàm gọi, tham số truyền,v.v…Một thuộc tính tham chiếu ghi this​, sử dụng suốt trình thực thi hàm Trong chương tiếp theo, ta học cách tìm call-site hàm để xác định việc thực thi ràng buộc this​như Ôn tập (TL;DR) Ràng buộc this​ đề tài gây bối rối cho nhiều lập trình viên JavaScript chưa bỏ thời gian tìm hiểu chế thực chất hoạt động Việc đoán, thử sai, chép mù quáng từ câu trả lời từ Stack Overflow cách hiệu để tận dụng chế this​ quan trọng Cho dù giả định hay quan niệm sai lầm dẫn lối, để học this​, bạn phải học this​ Bản thân this tham chiếu đến hàm, tham chiếu đến lexical scope hàm this​ thực ràng buộc tạo hàm gọi, tham chiếu xác định call-site nơi hàm gọi ... Nó thường dẫn ch? ??ng lợi ? ?ch linh động ch? ?ơng trình c? ?ch cho phép biến đại diện cho giá trị cho dù kiểu giá trị thời điểm theo chu trình logic ch? ?ơng trình JavaScript sử dụng c? ?ch tiếp cận thứ... biết JS để bạn khởi đầu trở thành lập trình viên JS Ch? ?ng ta giới thiệu vài nguyên lý ch? ?ơng c? ?ch không đầy đủ phần s? ?ch YDKJS​ Bạn nghĩ ch? ?ơng mục khái quát chuyên đề series Đặc biệt JS mẻ... thông d? ?ch mã Một số ngôn ngữ khác, d? ?ch hoàn thiện trước, gọi biên d? ?ch mã, sau ch? ?ơng trình ch? ??y, ch? ??y biên d? ?ch xong máy sẵn sàng ch? ??y JavaScript thường khẳng định ngơn ngữ thơng d? ?ch, mã nguồn

Ngày đăng: 15/03/2023, 16:15

w