0

javascript ư? bạn chưa biết hết về nó đâu

Mayfest2023

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

Tham Khảo


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí