EloquentJavascript - Chương 1 (values , type and operator)
Chapter 1
" Bên trong chiếc máy tính của bạn , chương trình hoạt động , rất uyển chuyển với các eletron chúng tán xạ rồi tập hợp lại . Những gì bạn thấy trên màn hình như bạn nhìn thấy sóng trên mặt nước , bản chất chương trình hoạt động như thế nào nằm bên trong máy tính nó vô hình với tất cả chúng ta."
Trong thế giới của máy tính chỉ có dữ liệu . Bạn có thể đọc dữ liệu , sửa đổi và tạo mới nhưng dữ liệu đó không thể được đề cập (but that which isn't data cannot be mentioned) . Tất cả dữ liệu đều được lưu trữ dưới dạng các chuỗi dài của các bit và do đó chúng về cơ bản là giống nhau.
Bít là đại diện cho 2 giá trị 0 hoặc 1.Bên trong máy tính chúng có các dạng như điện tích cao hoặc thấp , tín hiệu mạnh hay yếu . Bất kì mẩu thông tin nào cũng có thể biểu diễn thành một chuỗi các số 0 và 1 qua đó chúng ta có thể biểu diễn bất kì loại dữ liệu nào thông qua bit.
Ví dụ chúng ta biểu diễn số 13 ở cơ số 10 thông qua cơ số nhị phân..thay vì biểu diễn số 13 ở hệ số 10 chúng ta biểu diễn nó thông qua cơ số 2. 13 = 00001101
Value(Giá trị)
Hãy tưởng tương một đại dương thay vì nước là nhưng bit dữ liệu , một máy tính hiện đại ngày nay có thể lưu trữ 30 tỷ bit thậm chí còn lớn hơn. Để làm việc với lượng dữ liệu lớn như vậy mà không bị mất đi , chúng ta phải tách chúng thành các chunk (khối) đại diện cho các mẩu thông tin. Ví dụ như chuỗi 0011011 là một chunk đại diện cho số 13Trong môi trường JavaScript , các chunk này được gọi là các giá trị (values).
Mặc dù các chunk này đều được lưu trữ dưới dạng bit nhưng tất nhiên chúng đóng vai trò khác nhau , mỗi giá trị có một loại (type) xác định vai trò của nó , một số giá trị là số , hay text hoặc các hàm...
Để tạo một giá trị , bạn chỉ cần gọi tên của nó. Điều này thật là thuận tiện vì bạn không cần phải thu thập từng bit (bạn không cần thu thập từng bit ..lấy 0 rồi lấy 1 rồi lấy 1..bla bla để tạo thành một mẩu dữ liệu nào đó) .Bạn chỉ cần gọi tên của type chunk và whoooo bạn đã tạo ra được chúng.Chúng không được tạo ra từ không khí , tất nhiên rồi ^^.Mọi giá trị đều được lưu trữ ở đâu đó và nếu bạn sử dụng chúng đồng thời bạn có nguy cơ hết bộ nhớ . May mắn thay đây chỉ là vấn đề nếu bạn cần sử dụng tất cả chúng cùng một lúc , khi bạn không sử dụng đến nó nữa cơ chế dọn dẹp của JS sẽ xóa chúng trong bộ nhớ để lại các bit mà trước đây đã lưu trữ nó để có thể sử dụng lưu trữ dữ liệu.
Chương này giới thiệu sơ lược về những thứ cốt lõi của các chương trình js , các giá trị đơn giản các toán tử giúp chúng ta tương tác với các giá trị đó.
Numbers(Số)
Nhắc lại values (giá trị) là chunk (mỗi chunk đại diện cho một mẩu thông tin) , các giá trị biểu diễn kiểu số trong một chương trình JavaScript chúng được viết như sau.
Bạn tạo ra một value có type là number , khi chạy code này một chuỗi bit (chunk) đại diện cho số 13 sẽ xuất hiện trong bộ nhớ máy tính.
JavaScript sử dụng một số bit cố định , 64 trong số chúng để lưu trữ một giá trị số duy nhất . từ đó ta có thể thấy số lượng các số khác nhau được biểu diễn bị giới hạn.
Bộ nhớ máy tính trong quá khứ có dung lượng nhỏ hơn rất nhiều và mọi người có xu hướng sử dụng các nhóm 8 và 16 bit để biển diễn số của họ trong bộ nhớ máy tính điều này rất dễ dẫn đến hiện tượng tràn bộ nhớ do 8 bit và 16 bit đồng nghĩa với việc biểu diễn được ít số hơn , giới hạn của các số bị thu hẹp. Ngày nay một bộ nhớ 500GB có thể đút vừa trong túi của bạn và sử dụng các khối 64 bit bạn chỉ cần lo lắng hiện tượng tràn bộ nhớ khi xử lý các con số ở cấp độ thiên văn. (64 bit biểu diễn được xấp xỉ (1.8 tỷ tỷ số đó là rất nhiều)
Không phải tất cả các số nhỏ hơn 2^64 đều có thể khai báo trong JavaScript . các bit cũng lưu trữ các số âm , vì vậy một bit cho biết dấu của số đó . Để làm được điều này một số bit được sử dụng để lưu trữ vị trí của dấu thập phân . Như vậy số lượng tối đa thực tế có thể được lưu trữ là 9 triệu tỷ 9*10^15
Trong JavaScript các tính toán với số nguyên (còn gọi là integers) nhỏ hơn 9 triệu tỷ được đảm bảo luôn chính xác . Nhưng thật không may tính toán với số thập phân (phân số) thường không . Một ví dụ điển hình là số pi không thể được biểu thị chính xác bằng chữ số thập phân hữu hạn . số pi trong js bị mất đi tính chính xác vì chỉ có 64 bit để lưu trữ chúng. Điều này thật là xấu hổ , nhưng nó gây ra vấn đề thực tế chỉ trong các tình huống cụ thể . Điều quan trọng là phải nhận thức được nó và coi các kết quả của phép tính cho ra kết quả số thập phân vô tỷ không phải là kết quả chính xác.
Arithmetic (Số học)
Những công việc chính để thao tác với các giá trị kiểu số là số học (đoạn này chưa hiểu ý tác giả lắm) .Các phép toán số học như cộng trừ nhân chia ... trong js chúng ta biểu diễn các phép toán kiểu như thế này.
Các kí hiệu + hay * được gọi là các operators (toán tử) . Các đầu tiên là viết tắt của phép cộng , các thứ 2 là viết tắt của phép nhân. Đặt một toán tử giữa 2 giá trị sẽ áp dụng nó cho các giá trị đó và tạo ra một giá trị mới.
Trong ví dụ trên có nghĩa là cộng thêm 4 rồi nhân với 11 , thứ tự phép tính được thực hiện như thế nào ? Như bạn đoán phép nhân xảy ra trước tiên nhưng trong toán học , bạn có thể thay đổi điều này bằng cách cho những phép toán bạn muốn thực hiện đầu tiên vào trong cặp ngoặc.
Special numbers (những giá trị kiểu số đặc biệt)
Có ba giá trị đặc biệt trong JavaScript được coi là số nhưng khi thao tác với chúng , chúng ta không thao tác như với những giá trị kiểu number thông thường.
NaN là viết tắt của (not a number) là kết quả của một phép tính , mặc dù kết quả mong muốn trong trường hợp này thường là các giá trị kiểu số. Bạn sẽ nhận được kết quả này khi bạn cố gắng tính toán các phép toán kiểu như 0/0 hay Infinity - Infinity . hoặc bất kì một phép toán nào mà không mang lại một kết quả có ý nghĩa.
Strings (chuỗi)
Kiểu dữ liệu cơ bản tiếp theo là chuỗi , chuỗi được sử dụng để đại diện cho dữ liệu dạng text . Nó được tạo ra bằng cách khai báo nội dung rồi cho nó vào trong cặp dấu ngoặc kép. (bạn có thể sử dụng dấu nháy đơn hoặc dấu backtick miễn là đầu cuối phải khớp nhau)
Hầu như mọi kí tự đều có thể được đặt giữa các trích dẫn và js sẽ tạo ra một giá trị kiểu chuỗi từ nó nhưng có một vài trường hợp đặc biệt , một số kí tự bạn cần lưu ý nếu muốn đặt nó bên trong các trích dẫn.Bạn có thể tưởng tượng rằng đặt dấu ngoặc kép giữa các trích dẫn thật khó khăn.Chú ý thêm rằng khi bạn đang khi báo trong một cặp trích dẫn mà bạn nhấn enter nó có thể được thêm vào bên trong chuỗi mà không bị tự động lược bỏ đi khi vào chỉ khi bạn tạo trích dẫn bằng cặp dấu backticks.
Để có thể thêm các ký tự đặc biệt như vậy trong một chuỗi , mỗi ký tự đặc sau được khai báo bạn để thêm dấu gạch chéo ngược (\) nó sẽ chỉ ra rằng ký tự đằng sau nó là kí tự đặc biệt . Khi một kí tự n xuất hiện sau dấu gạch chéo nó được hiểu nào một dòng mới. Tương tự . kí tự t sau dấu gạch chéo ngược có nghĩa là một lần nhấn tab . Ví dụ :
Đoạn văn bản được in ra sẽ trông như thế này.
Tất nhiên có những tình huống mà bạn muốn dấu gạch chéo ngược chỉ là dấu gạch chéo ngược chứ không muốn coi nó như một kí tự đặc biệt để thông báo nữa , để làm được điều này bạn chỉ cần gõ 2 dấu gạch chéo ngược sát nhau như vậy js chỉ hiển thị kết quả ra một dấu thôi ^^.
Chuỗi cũng vậy nó cần được dịch thành một dãy các bit để có thể được lưu trữ và thao tác bởi máy tính. Javascript thực hiện điều này (dịch các chuỗi sang bit) dựa trên chuẩn Unicode . Unicode có thể mã hóa gần như tất cả các kí tự trong bất kì ngôn ngữ nào thông dùng (bao gồm các kí tự trong tiếng Hy Lạp , Ả Rập , Nhật Bản , Armenia...). Nếu chúng ta quy ước (dựa trên chuẩn Unicode) rằng mỗi kí tự trong chuỗi được dịch sang một số do Unicode quy định như vậy rõ ràng một chuỗi có thể được mô tả được bằng một chuỗi các số từ đó ta có thể dịch chuỗi các số này sang bit.^^.
Và đó là những gì JavaScript làm . Nhưng có một vấn đề phát sinh : Đại diện Javascript sử dụng 16 bit để mã hóa cho mỗi kí tự trong chuỗi và nó có thể mô tả 216 ký tự khác nhau.. Nhưng thằng Unicode có thể định nghĩa nhiều hơn số đó khoảng gấp đôi ^^ ở phiên bản hiện tại. Vì vậy một số ký tự , chẳng hạn như những emoji (nó sẽ chiếm 2 ký tự) trong chuỗi ở javascript . Chúng ta sẽ quay lại vấn đề này vào chương 5.
Các chuỗi không thể được chia , nhân hoặc trừ , nhưng toán tử + có thể được sử dụng khi thao tác với chúng. Kết quả của phép cộng các chuỗi sẽ không thêm . mà nó sẽ kết hợp với nhau . nó dán 2 chuỗi lại với nhau . Dòng sau sẽ tạo ra chuỗi "concatenate" :
Đối với chuỗi có một số hàm (phương thức) có thể thao tác với chúng . Mình sẽ quay lại nói về các hàm này trong chương 4.
Các chuỗi được bao bọc bằng các trích dẫn dấu ngoặc đơn hoặc kép hay backticks nó hoạt động khá giống nhau , có lẽ sự khác biệt duy nhất là bạn cần chú ý khi truyền một biến vào trong chuỗi vì mỗi trích dẫn có một kiểu làm riêng . Đối với chuỗi sử dụng backticks là trích dẫn (template literals) có thể làm thêm một vài thủ thuật. Ngoài việc thêm các dòng (đối với trích dẫn ngoặc đơn hoặc ngoặc kép khi ấn enter nó sẽ không hiều) nó còn có thể nhúng các giá trị rất dễ dàng.
Không phải tất cả các toán tử đều được biểu diễn dưới dạng biểu tượng (+ - * %) một số được viết dưới dạng từ . Ví dụ điển hình là typeof , vai trò của toán tử này giúp xác định kiểu nó giá trị mà bạn truyền vào trong nó.
Chuỗi cũng vậy nó cần được dịch thành một dãy các bit để có thể được lưu trữ và thao tác bởi máy tính. Javascript thực hiện điều này (dịch các chuỗi sang bit) dựa trên chuẩn Unicode . Unicode có thể mã hóa gần như tất cả các kí tự trong bất kì ngôn ngữ nào thông dùng (bao gồm các kí tự trong tiếng Hy Lạp , Ả Rập , Nhật Bản , Armenia...). Nếu chúng ta quy ước (dựa trên chuẩn Unicode) rằng mỗi kí tự trong chuỗi được dịch sang một số do Unicode quy định như vậy rõ ràng một chuỗi có thể được mô tả được bằng một chuỗi các số từ đó ta có thể dịch chuỗi các số này sang bit.^^.
Và đó là những gì JavaScript làm . Nhưng có một vấn đề phát sinh : Đại diện Javascript sử dụng 16 bit để mã hóa cho mỗi kí tự trong chuỗi và nó có thể mô tả 216 ký tự khác nhau.. Nhưng thằng Unicode có thể định nghĩa nhiều hơn số đó khoảng gấp đôi ^^ ở phiên bản hiện tại. Vì vậy một số ký tự , chẳng hạn như những emoji (nó sẽ chiếm 2 ký tự) trong chuỗi ở javascript . Chúng ta sẽ quay lại vấn đề này vào chương 5.
Các chuỗi không thể được chia , nhân hoặc trừ , nhưng toán tử + có thể được sử dụng khi thao tác với chúng. Kết quả của phép cộng các chuỗi sẽ không thêm . mà nó sẽ kết hợp với nhau . nó dán 2 chuỗi lại với nhau . Dòng sau sẽ tạo ra chuỗi "concatenate" :
Đối với chuỗi có một số hàm (phương thức) có thể thao tác với chúng . Mình sẽ quay lại nói về các hàm này trong chương 4.
Các chuỗi được bao bọc bằng các trích dẫn dấu ngoặc đơn hoặc kép hay backticks nó hoạt động khá giống nhau , có lẽ sự khác biệt duy nhất là bạn cần chú ý khi truyền một biến vào trong chuỗi vì mỗi trích dẫn có một kiểu làm riêng . Đối với chuỗi sử dụng backticks là trích dẫn (template literals) có thể làm thêm một vài thủ thuật. Ngoài việc thêm các dòng (đối với trích dẫn ngoặc đơn hoặc ngoặc kép khi ấn enter nó sẽ không hiều) nó còn có thể nhúng các giá trị rất dễ dàng.
Unary operators (toán tử đơn phương)
Chúng tôi sẽ sử dụng console.log để chỉ hiển thị những thứ mong muốn . Để tìm hiểu về console.log hãy xem chương tiếp theo.
Các toán tử thường cần 2 giá trị để thực hiện được nhiệm vụ của nó nhưng typeof chỉ cần một . Các toán tử sử dụng hai giá trị được gọi là toán tử nhị phân (binary operators) trong khi các toán tử chỉ cần một giá trị để thực hiện nhiệm vụ gọi là toán tử đơn nguyên (unary operators). Toán tử trừ có thể được sử dụng cả toán tử nhị phân và toán tử đơn nguyên.
Boolean values
Giá trị kiểu này thường hữu ích khi có một giá trị chỉ nằm 1 trong 2 khả năng và trong javascript ta có loại Boolean để phục vụ điều này. chỉ có 2 giá trị đúng và sai được viết dưới dạng nhưng từ đó (true và false) nó không phải string nên không cho nó vào trong trích dẫn nhé.
Comparison
Các dấu > và < là các ký hiệu truyền thống cho dấu lớn và dấu nhỏ hơn . áp dụng các toán tử này dẫn đến một giá trị kiểu Boolean cho biết liệu chúng có đúng trong trường hợp đó hay không ?
Chuỗi có thể được so sánh theo cùng một cách .
Các chuỗi được sắp xếp gần như đều là chữ cái nhưng không phải là những gì bạn muốn thấy trong tử điển : các chữ cái viết hoa luôn luôn "bé hơn" so với các loại chữ thường , vì vậy "Z" <"a". Khi so sánh các chuỗi , Javascript đi qua từng ký tự từ trái sang phải , so sánh theo mã Unicode.
Chỉ có một giá trị culon trong Javascript mà nó không bằng chính nó là NaN .
NaN được cho là biểu thị kết quả của một tính toán vô nghĩa và như vậy nó không bằng với kết quả của bất kỳ tính toán vô nghĩa nào khác.
Khi chúng ta kết hợp các toán tử Boolean này với số học và các toán tử khác , không phải lúc nào cũng cần dấu ngoặc đơn để bao bọc chúng. Trong số các toán tử logic mà chúng ta đã học sắp xếp theo mức ưu tiên từ thấp đến cao là :
|| <&&< (< , >) < == , === < (+ , - , * , / )
2 ==2 && 100 > 50 => true
Khi bạn muốn kiểm tra xem một giá trị có xác định hay hay nó bị underfine hoặc null , bạn có thể so sánh nó với null thông qua toán tử (== hoặc !=) . Nhưng nếu bạn muốn phân biệt null với false hoặc false với underfine thì sao , để giải quyết vấn đề này bạn hãy sử dụng toán tử ==== , nó sẽ ngăn chặn việc js tự ý ép kiểu bất kì giá trị nào trong biểu thức.
Chuỗi có thể được so sánh theo cùng một cách .
Các chuỗi được sắp xếp gần như đều là chữ cái nhưng không phải là những gì bạn muốn thấy trong tử điển : các chữ cái viết hoa luôn luôn "bé hơn" so với các loại chữ thường , vì vậy "Z" <"a". Khi so sánh các chuỗi , Javascript đi qua từng ký tự từ trái sang phải , so sánh theo mã Unicode.
Chỉ có một giá trị culon trong Javascript mà nó không bằng chính nó là NaN .
NaN được cho là biểu thị kết quả của một tính toán vô nghĩa và như vậy nó không bằng với kết quả của bất kỳ tính toán vô nghĩa nào khác.
Logical operators
Ngoài ra còn có một số thao tác có thể được áp dụng cho chính các Boolean cũng sẽ trả về các giá trị Boolean . Javascript hỗ trợ ba toán tử logic and , or and not. Đây có lẽ là những thứ toán tử được kết hợp với if else để handle lệnh nhiều nhất.Khi chúng ta kết hợp các toán tử Boolean này với số học và các toán tử khác , không phải lúc nào cũng cần dấu ngoặc đơn để bao bọc chúng. Trong số các toán tử logic mà chúng ta đã học sắp xếp theo mức ưu tiên từ thấp đến cao là :
|| <&&< (< , >) < == , === < (+ , - , * , / )
2 ==2 && 100 > 50 => true
Khi bạn muốn kiểm tra xem một giá trị có xác định hay hay nó bị underfine hoặc null , bạn có thể so sánh nó với null thông qua toán tử (== hoặc !=) . Nhưng nếu bạn muốn phân biệt null với false hoặc false với underfine thì sao , để giải quyết vấn đề này bạn hãy sử dụng toán tử ==== , nó sẽ ngăn chặn việc js tự ý ép kiểu bất kì giá trị nào trong biểu thức.
Empty values
Có 2 giá trị đặc biệt mà bạn cần quan tâm là null và underfine , chúng được sử dụng đê biểu thị sự vắng mặt của một giá trị có ý nghĩa . Bản thân của chúng là những giá trị nhưng nó chúng không mang thông tin.
Nhiều tác vụ trong Javascript không tạo ra một giá trị có ý nghĩa (bạn sẽ thấy những tác vụ sau)
ví dụ như underfine.
Sự khác biệt giữa null và underfine là một sự cố thiết kế trong javascript và trong hầu hết mọi trường hợp nó không phát sinh ra vấn đề. Trong trường hợp bạn thực sự phải quan tâm và thao tác với 2 giá trị này , tôi khuyên bạn nên coi chúng có thể hoán đổi cho nhau.
Automatic type conversion
Trong phần giới thiệu , tôi đã đề cập rằng javascript có thể vượt quá khả năng chấp nhận hầu hết mọi cchương trình bạn cung cấp , ngay cả những biểu thức kì lạ . Điều này được thể hiện độc đáo bằng các ví dụ sau.
Nhưng ở biểu thức số 2 'số 1' từ kiểu number lại được ép thành kiểu chuỗi (có thể thấy nó sẽ ưu tiên ép thành kiểu chuỗi nếu không ép được thành chuỗi ví dụ như ở biểu thức số 2 , thằng javascript không ép được 1 kiểu number về string vì nếu ép thì nó chả ra cái mẹ gì cả nên nó ép thằng "5" kiểu string về chuỗi).
Ở biểu thức số 3 thằng javascript nó có 2 lựa chọn ép "five" về kiểu số , cách này không được lý do vì sao thì ai cũng biết ^^ . cách 2 là ép 2 kiểu number về kiểu string nhưng nếu nhu vậy thì kết quả ra cái khỉ gió gì ??? => kết quả ra NAN (javascript thể hiện rằng kết quả của biểu thức này không phải một số như bạn mong muốn ".
Khi so sánh các giá trị cùng loại bằng cách sử dụng toán tử "==" , kết quả rất dễ dự đoán : bạn sẽ được trả về true nếu 2 giá trị giống nhau ngoại trừ trong trường hợp NaN . Nhưng khi các loại khác nhau , Javascript sử dụng một bộ quy tắc phức tạp và khó hiểu để xác định những việc cần làm.
Trong hầu hết các trường hợp , nó chỉ cố gắng chuyển đổi một trong 2 giá trị sang loại giá trị khác . Tuy nhiên khi null hoặc underfine xảy ra ở cả 2 bên của toán tử đều là null hoặc underfine








Nhận xét
Đăng nhận xét