Giới thiệu
chào các bạn, hôm nay tôi lại đem đến cho các bạn những kiến thức mới về javascript mà có thể kể cả những bạn đã học lâu về javascript cũng chưa chắc đã biết đến, chúng ta cùng bắt đầu nào
Var, let & const
chắc các bạn đã quá quen với việc khai báo biến với var, let, const rồi đúng không?, tuy nhiên, nếu bạn chưa tìm hiểu kĩ về js, hẳn các bạn sẽ không biết tại sao mọi người thường khuyến nghị dùng let và const thay vì var, chúng ta sẽ tìm hiểu về nó ngay dưới đây
a. về mặt scope
Var
theo docs của mozilla, từ khóa var có 2 loại scope là function scope hoặc global scope
The var statement declares a function-scoped or globally-scoped variable, optionally initializing it to a value.
let
theo docs của mozilla, từ khóa let chỉ có block scope
The let declaration declares a block-scoped local variable
Vậy tại sao chúng ta phải quan tâm về vấn đề này, thì tôi sẽ đưa ra 2 ví dụ sau đây:
vd1: từ khóa var
var x = 1; if (x === 1) { var x = 2; console.log(x); // Expected output: 2
}
console.log(x);
// Expected output: 2
các bạn có thể để ý rằng giá trị từ biến x sẽ không mất đi kể cả đi ra khỏi block code if
vd2: từ khóa let
let x = 1; if (x === 1) { let x = 2; console.log(x); // Expected output: 2
}
console.log(x);
// Expected output: 1
đối với từ khóa let, giá trị của nó sẽ mất đi ngay khi ra khỏi block code if
Tại sao đây lại là vấn đề ?
các bạn thử giả sử rằng có 2 người đang code trong cùng nơi như trong ví dụ trên và cùng sử dụng biến var, tuy nhiên đồng nghiệp bạn lại gán lại giá trị như trong vd1, điều đó có thể khiến logic của bạn từ đúng trở thành sai ngay khi code được merge
b. về mặt hoisting
var
var khi hoisting sẽ tự động gán giá trị undefined, phần khởi tạo giá trị sẽ không được hoisted theo
It's important to point out that only a variable's declaration is hoisted, not its initialization. The initialization happens only when the assignment statement is reached. Until then the variable remains undefined
vd:
console.log(x); //undefined
var x = 2;
console.log(x); //2
let
let sau khi hoisted nó sẽ ở trong temporal dead zone(TDZ) cho đến khi nào biến được khởi tạo
lưu ý: các biến nằm trong TDZ sẽ bị lỗi ReferenceError
let allows you to declare variables that are limited to the scope of a block statement, or expression on which it is used, unlike the var keyword, which declares a variable globally, or locally to an entire function regardless of block scope. The other difference between var and let is that the latter can only be accessed after its declaration is reached (see temporal dead zone). For this reason, let declarations are commonly regarded as non-hoisted.
console.log(x); //báo lỗi ReferenceError: Cannot access 'x' before initialization -> thoát khỏi chương trình let x = 2; console.log(x);
lưu ý: việc nó ở trong TDZ sẽ khác với việc các bạn không gán giá trị, nếu bạn không gán giá trị nó sẽ là undefined
let x;
console.log(typeof x); //undefined
c. vậy tại sao hiện tại mọi người vẫn thích sử dụng biến var
lưu ý: mình chưa code đủ lâu để có thể hiểu được tất cả mọi người nên những ý kiến dưới đây là những gì mình nghĩ, search và cảm nhận được
- có thể bạn là một lập trình viên web lâu năm, bạn đã làm web từ những năm 2010 chẳng hạn và việc sử dụng var đã quá quen
- bạn đang phải maintain hoặc phải handle cho những trình duyệt, phiên bản trình duyệt cũ kĩ
- bạn có thể đang không hiểu rõ về các từ khóa này )
Template strings
đây là cách tạo ra một chuỗi string với biến nội suy bằng dấu ``, với nó ta không cần phải build chuỗi bằng cách nối chuỗi như trước kia mà thay vào đó bạn có làm như sau
let is_locked = false;
let style_of_lock = `lock ${ is_locked ? 'locked' : 'unlock' }`
console.log(style_of_lock) // lock unlock
hoặc tạo ra 1 đoạn văn chỉ bằng việc cách dòng
let para = `this is line 1
this is line 2
`
console.log(para)
/*output:
this is line 1
this is line 2
*/
Tagged templates
nó cho phép bạn parse template strings với một function vd:
function lockStyle(normalStyle, is_locked, ...rest) { return `${normalStyle[0]} ${is_locked ? 'locked' : 'unlock'}`
}
const style_of_lock = lockStyle`lock lock-red lock-fe${true}`;
console.log(style_of_lock) //lock lock-red lock-fe locked
destructuring & toán tử rest
destructuring và toán tử rest:
- với mảng:
let arr = [1,2,3,4,5];
let [a,,c] = arr;
console.log(a,c) //1 3 // hoặc sử dụng toán tử rest let arr = [1,2,3,4,5];
let [a,,c,...conlai] = arr; // dùng 2 dấu ,, để loại số 2
console.log(a,c,conlai) //1 3 [ 4, 5 ]
- với object
let obj = { name: 'ttdat', age: NaN, address: 'HCM'
} let { name, age, ...conlai } = obj;
console.log( age, conlai) // NaN {address: 'HCM'}
- sử dụng toán tử rest với function
function sum(...args) { let sum = 0; for (const key of args) { sum += key; } console.log(sum);
}
sum(1,2,3); //6
sum(1,2); //3
sum(1,3); // 4
Lời kết và hứa hẹn
bài viết đã dài rồi nên mình tính kết thúc ở đây luôn, có lẽ mình sẽ viết tiếp phần 2 với toàn bộ các nội dung về xử lí bất đồng bộ hứa hẹn sẽ có Callback, promise, observable. Các bạn nhớ đón xem và cho mình một upvote nhaaaa