Khám phá JavaScript chức năng được đặt tên là một trong những sách Lập trình hàm mới hay nhất của BookAuthority!
JavaScript có nguyên hàm, đối tượng và hàm. Tất cả chúng đều là giá trị. Tất cả đều được coi là đối tượng, thậm chí là nguyên thủy.
nguyên thủy
Số, boolean, chuỗi, undefined
và null
là nguyên thủy.
Con số
Chỉ có một loại số trong JavaScript, loại dấu phẩy động nhị phân 64 bit. Số học của số thập phân là không chính xác.
Như bạn có thể đã biết, 0.1 + 0.2
Không làm 0.3
. Nhưng với số nguyên, số học là chính xác, vì vậy 1+2 === 3
.
Các số kế thừa các phương thức từ Number.prototype
vật. Các phương thức có thể được gọi trên các số:
(123).toString(); //"123"
(1.23).toFixed(1); //"1.2"
Có các chức năng để chuyển đổi chuỗi thành số: Number.parseInt()
, Number.parseFloat()
và Number()
:
Number.parseInt("1") //1
Number.parseInt("text") //NaN
Number.parseFloat("1.234") //1.234
Number("1") //1
Number("1.234") //1.234
Các phép toán số học không hợp lệ hoặc chuyển đổi không hợp lệ sẽ không tạo ra ngoại lệ, nhưng sẽ dẫn đến NaN
Giá trị “Không phải là số”. Number.isNaN()
có thể phát hiện NaN
.
Các +
Toán tử có thể thêm hoặc nối.
1 + 1 //2
"1" + "1" //"11"
1 + "1" //"11"
Chuỗi
Một chuỗi lưu trữ một loạt các ký tự Unicode. Văn bản có thể nằm trong dấu ngoặc kép ""
hoặc dấu nháy đơn ''
.
Các chuỗi kế thừa các phương thức từ String.prototype
. Họ có các phương pháp như: substring()
, indexOf()
và concat()
.
"text".substring(1,3) //"ex"
"text".indexOf('x') //2
"text".concat(" end") //"text end"
Chuỗi, giống như tất cả các chuỗi nguyên thủy, là bất biến. Ví dụ concat()
không sửa đổi chuỗi hiện có mà tạo chuỗi mới.
Boolean
Một boolean có hai giá trị: true
và false
.
Ngôn ngữ có giá trị thật và giả.false
, null
, undefined
, ''
(chuỗi trống), 0
và NaN
là giả mạo. Tất cả các giá trị khác, bao gồm tất cả các đối tượng, là trung thực.
Giá trị trung thực được đánh giá true
khi được thực thi trong ngữ cảnh boolean. Giá trị sai được ước tính thành false
. Hãy xem ví dụ tiếp theo hiển thị false
chi nhánh.
let text="";
if(text) {
console.log("This is true");
} else {
console.log("This is false");
}
Toán tử đẳng thức là ===
. Toán tử không bằng là !==
.
Biến
Các biến có thể được xác định bằng cách sử dụng var
, let
và const
.
var
khai báo và tùy ý khởi tạo một biến. Các biến được khai báo với var
có một phạm vi chức năng. Chúng được coi như đã khai báo ở đầu hàm. Điều này được gọi là nâng biến.
Các let
khai báo có phạm vi khối.
Giá trị của một biến không được khởi tạo là undefined
.
Một biến được khai báo với const
không thể gán lại. Tuy nhiên, giá trị của nó vẫn có thể thay đổi được. const
đóng băng biến, Object.freeze()
đóng băng đối tượng. Các const
khai báo có phạm vi khối.
Các đối tượng
Một đối tượng là một tập hợp động các thuộc tính.
Khóa thuộc tính là một chuỗi duy nhất. Khi một chuỗi không phải được sử dụng làm khóa thuộc tính, nó sẽ được chuyển thành chuỗi. Giá trị thuộc tính có thể là một nguyên hàm, đối tượng hoặc hàm.
Cách đơn giản nhất để tạo một đối tượng là sử dụng một đối tượng theo nghĩa đen:
let obj = {
message : "A message",
doSomething : function() {}
}
Có hai cách để truy cập các thuộc tính: ký hiệu dấu chấm và ký hiệu dấu ngoặc. Chúng ta có thể đọc, thêm, chỉnh sửa và loại bỏ các thuộc tính của đối tượng bất cứ lúc nào.
- được:
object.name
,object[expression]
- bộ:
object.name = value,
object[expression] = value
- xóa bỏ:
delete object.name
,delete object[expression]
let obj = {}; //create empty object
obj.message = "A message"; //add property
obj.message = "A new message"; //edit property
delete obj.message; //delete property
Các đối tượng có thể được sử dụng làm bản đồ. Một bản đồ đơn giản có thể được tạo bằng cách sử dụng Object.create(null)
:
let french = Object.create(null);
french["yes"] = "oui";
french["no"] = "non";
french["yes"];//"oui"
Tất cả các thuộc tính của đối tượng là công khai. Object.keys()
có thể được sử dụng để lặp lại trên tất cả các thuộc tính.
function logProperty(name){
console.log(name); //property name
console.log(obj[name]); //property value
}
Object.keys(obj).forEach(logProperty);
Object.assign()
sao chép tất cả các thuộc tính từ đối tượng này sang đối tượng khác. Một đối tượng có thể được sao chép bằng cách sao chép tất cả các thuộc tính của nó vào một đối tượng trống:
let book = { title: "The good parts" };
let clone = Object.assign({}, book);
Đối tượng bất biến là đối tượng một khi được tạo ra thì không thể thay đổi được. Nếu bạn muốn làm cho đối tượng không thay đổi, hãy sử dụng Object.freeze()
.
Nguyên thủy so với đối tượng
nguyên thủy (ngoại trừ null
và undefined
) được coi như các đối tượng, theo nghĩa là chúng có các phương thức nhưng chúng không phải là đối tượng.
Các số, chuỗi và booleans có các trình bao bọc tương đương đối tượng. Đây là những Number
, String
và Boolean
chức năng.
Để cho phép truy cập vào các thuộc tính trên nguyên thủy, JavaScript tạo một đối tượng bao bọc và sau đó hủy nó. Quá trình tạo và hủy các đối tượng trình bao được tối ưu hóa bởi công cụ JavaScript.
Nguyên thủy là bất biến, và các đối tượng có thể thay đổi.
Mảng
Mảng là tập hợp các giá trị được lập chỉ mục. Mỗi giá trị là một phần tử. Các phần tử được sắp xếp và truy cập theo số chỉ mục của chúng.
JavaScript có các đối tượng giống như mảng. Mảng được thực hiện bằng cách sử dụng các đối tượng. Các chỉ mục được chuyển đổi thành chuỗi và được sử dụng làm tên để truy xuất giá trị.
Một mảng đơn giản như let arr = ['A', 'B', 'C']
được mô phỏng bằng cách sử dụng một đối tượng như bên dưới:
{
'0': 'A',
'1': 'B',
'2': 'C'
}
Lưu ý rằng arr[1]
cho cùng một giá trị như arr['1']
: arr[1] === arr['1']
.
Xóa các giá trị khỏi mảng bằng delete
sẽ để lại lỗ hổng. splice()
có thể được sử dụng để tránh vấn đề, nhưng nó có thể chậm.
let arr = ['A', 'B', 'C'];
delete arr[1];
console.log(arr); // ['A', empty, 'C']
console.log(arr.length); // 3
Các mảng của JavaScript không đưa ra các ngoại lệ “chỉ mục nằm ngoài phạm vi”. Nếu chỉ mục không có sẵn, nó sẽ trở lại undefined
.
Ngăn xếp và hàng đợi có thể dễ dàng được thực hiện bằng cách sử dụng các phương thức mảng:
let stack = [];
stack.push(1); // [1]
stack.push(2); // [1, 2]
let last = stack.pop(); // [1]
console.log(last); // 2
let queue = [];
queue.push(1); // [1]
queue.push(2); // [1, 2]
let first = queue.shift();//[2]
console.log(first); // 1
Chức năng
Các chức năng là các đơn vị hành vi độc lập.
Chức năng là đối tượng. Các hàm có thể được gán cho các biến, được lưu trữ trong các đối tượng hoặc mảng, được truyền dưới dạng đối số cho các hàm khác và được trả về từ các hàm.
Có ba cách để xác định một chức năng:
- Khai báo hàm (còn gọi là Câu lệnh hàm)
- Biểu thức hàm (còn gọi là hàm chữ)
- Chức năng mũi tên
Khai báo hàm
function
là từ khóa đầu tiên trên dòng- nó phải có một cái tên
- nó có thể được sử dụng trước định nghĩa. Khai báo chức năng được di chuyển, hoặc “hoisted”, đến đầu phạm vi của họ.
function doSomething(){}
Biểu thức hàm
function
không phải là từ khóa đầu tiên trên dòng- tên là tùy chọn. Có thể có một biểu thức hàm ẩn danh hoặc một biểu thức hàm được đặt tên.
- nó cần được xác định, sau đó nó có thể thực thi
- nó có thể tự động thực thi sau khi định nghĩa (được gọi là “IIFE” Biểu thức hàm được gọi ngay lập tức)
let doSomething = function() {}
Chức năng mũi tên
Hàm mũi tên là một cú pháp đường để tạo một biểu thức hàm ẩn danh.
let doSomething = () => {};
Các hàm mũi tên không có hàm riêng this
và arguments
.
lời gọi hàm
Một chức năng, được xác định với function
từ khóa, có thể được gọi theo những cách khác nhau:
doSomething(arguments)
theObject.doSomething(arguments)
theObject["doSomething"](arguments)
new Constructor(arguments)
doSomething.apply(theObject, [arguments])
doSomething.call(theObject, arguments)
Các hàm có thể được gọi với nhiều hoặc ít đối số hơn so với khai báo trong định nghĩa. Các đối số bổ sung sẽ bị bỏ qua và các tham số bị thiếu sẽ được đặt thành undefined
.
Các hàm (ngoại trừ các hàm mũi tên) có hai tham số giả: this
và arguments
.
cái này
Phương thức là các chức năng được lưu trữ trong các đối tượng. Các chức năng là độc lập. Để một chức năng biết đối tượng nào sẽ hoạt động trênthis
Được sử dụng. this
đại diện cho bối cảnh của chức năng.
Không có điểm nào để sử dụng this
khi một hàm được gọi với dạng hàm: doSomething()
. Trong trường hợp này this
Là undefined
hoặc là window
đối tượng, tùy thuộc vào việc chế độ nghiêm ngặt có được bật hay không.
Khi một hàm được gọi với dạng phương thức theObject.doSomething()
,this
đại diện cho đối tượng.
Khi một hàm được sử dụng như một hàm tạo new Constructor()
, this
đại diện cho đối tượng mới được tạo.
Giá trị của this
có thể được thiết lập với apply()
hoặc call()
:doSomething.apply(theObject)
. Trong trường hợp này this
là đối tượng được gửi làm tham số đầu tiên cho phương thức.
Giá trị của this
phụ thuộc vào cách chức năng được gọi, không phải nơi chức năng được xác định. Điều này tất nhiên là một nguồn gây nhầm lẫn.
tranh luận
Các arguments
tham số giả cung cấp tất cả các đối số được sử dụng khi gọi. Đó là một đối tượng giống như mảng, nhưng không phải là một mảng. Nó thiếu các phương thức mảng.
function log(message){
console.log(message);
}
function logAll(){
let args = Array.prototype.slice.call(arguments);
return args.forEach(log);
}
logAll("msg1", "msg2", "msg3");
Một thay thế là cú pháp tham số nghỉ ngơi mới. Thời gian này args
là một đối tượng mảng.
function logAll(...args){
return args.forEach(log);
}
trở lại
Một chức năng không có return
tuyên bố trả về undefined
. Hãy chú ý đến việc tự động chèn dấu chấm phẩy khi sử dụng return
. Hàm sau sẽ không trả về một đối tượng trống, mà là một undefined
một.
function getObject(){
return
{
}
}
getObject()
Để tránh sự cố, hãy sử dụng {
trên cùng một dòng với return
:
function getObject(){
return {
}
}
Nhập động
JavaScript có kiểu gõ động. Giá trị có loại, biến thì không. Các loại có thể thay đổi trong thời gian chạy.
function log(value){
console.log(value);
}
log(1);
log("text");
log({message : "text"});
Các typeof()
toán tử có thể kiểm tra loại biến.
let n = 1;
typeof(n); //number
let s = "text";
typeof(s); //string
let fn = function() {};
typeof(fn); //function
một chủ đề duy nhất
Thời gian chạy JavaScript chính là luồng đơn. Hai chức năng không thể chạy cùng một lúc. Thời gian chạy chứa Hàng đợi sự kiện lưu trữ danh sách các thông báo sẽ được xử lý. Không có điều kiện chạy đua, không có bế tắc. Tuy nhiên, mã trong Hàng đợi sự kiện cần phải chạy nhanh. Nếu không, trình duyệt sẽ không phản hồi và sẽ yêu cầu hủy tác vụ.
ngoại lệ
JavaScript có một cơ chế xử lý ngoại lệ. Nó hoạt động như bạn có thể mong đợi, bằng cách gói mã bằng cách sử dụng try/catch
bản tường trình. Tuyên bố có một catch
khối xử lý tất cả các ngoại lệ.
Thật tốt khi biết rằng đôi khi JavaScript ưu tiên cho các lỗi im lặng. Mã tiếp theo sẽ không đưa ra ngoại lệ khi tôi cố sửa đổi một đối tượng bị đóng băng:
let obj = Object.freeze({});
obj.message = "text";
Chế độ nghiêm ngặt loại bỏ một số lỗi im lặng của JavaScript. "use strict";
cho phép chế độ nghiêm ngặt.
mẫu nguyên mẫu
Object.create()
hàm tạo và class
xây dựng các đối tượng trên hệ thống nguyên mẫu.
Xem xét ví dụ tiếp theo:
let servicePrototype = {
doSomething : function() {}
}
let service = Object.create(servicePrototype);
console.log(service.__proto__ === servicePrototype); //true
Object.create()
xây dựng một đối tượng mới service
trong đó cóservicePrototype
đối tượng làm nguyên mẫu của nó. Điều này có nghĩa rằng doSomething()
có sẵn trên service
vật. Điều đó cũng có nghĩa là các __proto__
tài sản của service
điểm đến servicePrototype
vật.
Bây giờ chúng ta hãy xây dựng một đối tượng tương tự bằng cách sử dụng class
.
class Service {
doSomething(){}
}
let service = new Service();
console.log(service.__proto__ === Service.prototype);
Tất cả các phương thức được định nghĩa trong Service
lớp sẽ được thêm vàoService.prototype
vật. Các trường hợp của Service
lớp sẽ có cùng một nguyên mẫu (Service.prototype
) vật. Tất cả các phiên bản sẽ ủy quyền các cuộc gọi phương thức cho Service.prototype
vật. Các phương thức được xác định một lần trênService.prototype
và sau đó được kế thừa bởi tất cả các trường hợp.
chuỗi nguyên mẫu
Các đối tượng kế thừa từ các đối tượng khác. Mỗi đối tượng có một nguyên mẫu và kế thừa các thuộc tính của chúng từ nguyên mẫu đó. Nguyên mẫu có sẵn thông qua thuộc tính “ẩn” __proto__
.
Khi bạn yêu cầu một thuộc tính mà đối tượng không chứa, JavaScript sẽ xem xét chuỗi nguyên mẫu cho đến khi tìm thấy thuộc tính được yêu cầu hoặc cho đến khi tìm đến cuối chuỗi.
Các mẫu chức năng
JavaScript có các hàm và bao đóng hạng nhất. Đây là những khái niệm mở đường cho Lập trình hàm trong JavaScript. Kết quả là, các chức năng bậc cao hơn là có thể.
filter()
, map()
, reduce()
là hộp công cụ cơ bản để làm việc với mảng theo kiểu hàm.
filter()
chọn các giá trị từ danh sách dựa trên hàm vị từ quyết định giá trị nào sẽ được giữ lại.
map()
chuyển đổi một danh sách các giá trị sang một danh sách các giá trị khác bằng cách sử dụng hàm ánh xạ.
let numbers = [1,2,3,4,5,6];
function isEven(number){
return number % 2 === 0;
}
function doubleNumber(x){
return x*2;
}
let evenNumbers = numbers.filter(isEven);
//2 4 6
let doubleNumbers = numbers.map(doubleNumber);
//2 4 6 8 10 12
reduce()
giảm danh sách các giá trị xuống một giá trị.
function addNumber(total, value){
return total + value;
}
function sum(...args){
return args.reduce(addNumber, 0);
}
sum(1,2,3); //6
Bao đóng là một hàm bên trong có quyền truy cập vào các biến của hàm cha, ngay cả sau khi hàm cha đã thực thi. Nhìn vào ví dụ tiếp theo:
function createCount(){
let state = 0;
return function count(){
state += 1;
return state;
}
}
let count = createCount();
console.log(count()); //1
console.log(count()); //2
count()
là một hàm lồng nhau. count()
truy cập biến state
từ cha mẹ của nó. Nó tồn tại khi gọi hàm cha createCount()
.count()
là một đóng cửa.
Hàm bậc cao hơn là một hàm lấy một hàm khác làm đầu vào, trả về một hàm hoặc thực hiện cả hai.
filter()
, map()
, reduce()
là các hàm bậc cao hơn.
Một hàm thuần túy là một hàm trả về một giá trị chỉ dựa trên đầu vào của nó. Các hàm thuần túy không sử dụng các biến từ các hàm bên ngoài. Các chức năng thuần túy không gây ra đột biến.
Trong các ví dụ trước isEven()
, doubleNumber()
, addNumber()
và sum()
là các hàm thuần túy.
Phần kết luận
Sức mạnh của JavaScript nằm ở sự đơn giản của nó.
Biết các nguyên tắc cơ bản về JavaScript giúp chúng ta hiểu và sử dụng ngôn ngữ này tốt hơn.
Học hỏi phản ứng chức năngtheo cách dựa trên dự án, với Kiến trúc chức năng với React và Redux.
Khám phá JavaScript chức năng được đặt tên là một trong những sách Lập trình hàm mới hay nhất của BookAuthority!
Để biết thêm về cách áp dụng các kỹ thuật lập trình chức năng trong React, hãy xem Phản ứng chức năng.
Theo dõi trên Twitter