You are on page 1of 14

𝐓𝐚̉𝐧 𝐦𝐚̣𝐧 𝐉𝐚𝐯𝐚𝐬𝐜𝐫𝐢𝐩𝐭

- Khi trình duyệt nhận được file HTML, nó sẽ chạy qua một chuỗi các bước để xây dựng và hiển
thị trang web:
1. Sử dụng file HTML để tạo DOM (Document Object Model).
2. Sử dụng CSS để tạo CSSOM (CSS Object Model).
3. Chạy script xử lý DOM và CSSOM đã có.
4. Kết hợp DOM và CSSOM để tạo nó thành Render Tree.
5. Bước Layout (xác định size và position của toàn bộ phần tử trên trang web).
6. Bước Paint, vẽ tất cả các pixel (hiển thị lên màn hình).
/* -------------------- */
DOM (Document Object Model) là Mô hình Đối tượng Tài liệu, DOM được dùng để truy xuất
các tài liệu dạng HTML, có dạng một cây cấu trúc dữ liệu.
/* -------------------- */
Javascript là ngôn ngữ lập trình đồng bộ và đơn luồng (single thread) các lệnh trong javascript
được thực hiện tuần tự từ trên xuống dưới, chỉ thực hiện 1 nhiệm vụ tại 1 thời điểm. Nhưng
Javascript có khả năng xử lý bất đồng bộ.
Sự bất đồng bộ trong javascript xuất hiện khi nó thao tác với các WebAPI (ajax, setTimeout(), …
). Khi một câu lệnh thao tác với WebAPI, nó sẽ mất một khoảng thời gian để chờ các dữ liệu trả
về từ WebAPI, do đó ở trong luồng chính của javascript, nó sẽ ở trong trạng thái chờ. Tuy nhiên
chương trình sẽ không bỏ trống khoảng thời gian chờ đó, chương trình sẽ tiếp tục thực hiện các
câu lệnh tiếp theo.
/* -------------------- */
Các cách để tăng tốc đột tải trang web:
- Tối ưu HTML, CSS, Javascript bằng cách nén thành file min.
- Lưu hình ảnh theo kích thước phù hợp, nén ảnh, (Ví dụ tinypng.com).
- Sử dụng ảnh thumbnail.
- Nếu có thể thì nên dùng ảnh SVG.
- Tải hình ảnh theo cách lazy loading để hiển thị trang đầu tiên nhanh hơn
- Những ảnh icon nhỏ thì nên dùng icon font nhưng font-awesome.
- Sử dụng các font có sẵn trên google.
- Loại bỏ các đoạn code CSS, Javascript thừa.
- Sửa các liên kết lỗi.
- Tối ưu hóa cơ sở dữ liệu, như tối ưu các query trong database.
- Sử dụng Google PageSpeed Insight để kiểm tra các yếu tố ảnh hưởng đến tốc độ.
/* -------------------- */
- Function scope: cả 3 var, let, const đều có.
- Block scope: var không có; let và const bị giới hạn trong phạm vi block.
- Redeclare: var khai báo lại được, let và const không được.
- Reassign: var và let thì gán lại được, const không được.
- Hoisting: var có, let và const không có.
Block scope đề cập đến ý tưởng rằng biến và hàm có thể thuộc một block bất kỳ (chính xác là
{...}).
/* -------------------- */
- Hoisting là việc đưa các khai báo biến và hàm được đưa lên lên phần đầu tiên của phạm vi mà
biến được sử dụng, chỉ đưa biến đó chứ ko đưa giá trị của biến đó lên đầu (biến đó sẽ là
undefined).
Ví dụ 1:
a = 2;
var a;
console.log(a); // 2
=> Hiểu theo cách javascript chạy thì có thể được viết như thế này:
var a; // Đây là giai đoạn biên dịch
a = 2; // Đây là giai đoạn thực thi
console.log(a);
Ví dụ 2:
console.log(a);
var a = 2; // undefined
=> Hiểu theo cách javascript chạy thì có thể được viết như thế này:
var a;
console.log(a); // undefined
a = 2;
Ví dụ 3:
foo(); // 1
var foo;
function foo() {
console.log(1);
}
=> Hiểu theo cách javascript chạy thì có thể được viết như thế này:
function foo() {
console.log(1);
}
foo(); // 1
- Để tránh hoisting sử dụng khai báo biến với let và const, việc khai báo sẽ không "tồn tại" cho
đến khi có biểu thức khai báo let hoặc const.
- Đọc cuốn You Don't Know JS (Có bản Tiếng Việt)
/* -------------------- */
- Khi khi chạy chương trình đến một biến, javascript sẽ bắt đầu tra cứu Scope thực thi gần nhất,
và nếu cần thiết (tức là nó không tìm thấy cái nó đang tìm trong đó), nó sẽ hoạt động bằng cách
đi lên trên Scope lồng nhau, trong một thời điểm việc tìm kiếm thực hiện cho đến khi nó đi lên
tầng cuối cùng toàn cục rồi dừng lại, kể cả có tìm thấy hay không.
/* -------------------- */
- Javascript có 5 kiểu dữ liệu đc truyền bằng value (kiểu nguyên thủy): String và Number,
Boolean, null, undefined, Symbol (kiểu symbol được thêm vào từ ES6).
- Javascript có 3 kiểu dữ liệu đc truyền bằng reference address: Array, Object, Function.
/* -------------------- */
- Node.js được viết bằng C++. Node.js dùng V8 Engine (là một javascript engine) để biên dịch
javascript trực tiếp sang mã máy trước khi thực thi nó.
/* -------------------- */
- API (Application Programming Interface) nghĩa là Giao diện lập trình ứng dụng, là một "giao
diện" giữa phần mềm với phần mềm, API là cách để các phần mềm giao tiếp với nhau.
- RESTful API: REST là từ viết tắt cho REpresentational State Transfer (Chuyển trạng thái đại
diện). RESTful API là một tiêu chuẩn dùng trong việc thiết kế các API cho các ứng dụng web để
quản lý các nguồn tài nguyên, quy định cách mà client và server sẽ tương tác với nhau. Trọng
tâm của REST quy định cách sử dụng các giao thức HTTP (như GET, POST, PUT, DELETE...).
https://bkaii.com.vn/.../334-khai-niem-co-ban-ve-restful-api
/* -------------------- */
- Closure là khi một hàm có khả năng nhớ và truy cập các biến của hàm cha ngay cả khi hàm cha
đã chạy xong.
- Closure là một hàm con được viết lồng vào bên trong một hàm cha, hàm con có thể sử dụng
biến toàn cục, biến cục bộ của hàm cha và biến cục bộ của chính nó. Khi hàm cha chạy xong, các
biến của hàm cha mà hàm con đang sử dụng sẽ không mất đi, mà javascript sẽ tạo một closure
cho hàm con, tạo những closure cho các biến mà hàm con truy xuất vào.
Dùng để giả lập việc khai báo các phương thức private, để viết kiểu module: Hữu dụng trong
việc giới hạn việc truy cập; Giữ các phương thức không cần thiết có thể làm xáo trộn những
phương thức public.
Ví dụ:
function makeFunc() {
var name = 'Mozilla';
function displayName() {
alert(name);
}
return displayName;
}
var myFunc = makeFunc();
myFunc();
Giải thích: Khi gọi hàm makeFunc() sẽ return về hàm displayName(), và chưa hề chạy qua đoạn
code trong hàm displayName().
Thoạt nhìn, đoạn code này sẽ không dễ nhận ra đoạn code này vẫn chạy bình thường. Trong một
số ngôn ngữ lập trình khác, biến cục bộ bên trong một hàm chỉ tồn tại trong quá trình hàm thực
thi. Một khi makeFunc() chạy xong, chúng ta sẽ nghĩ rằng biến name sẽ không còn thể truy cập
được. Tuy nhiên, đoạn code trên sẽ vẫn cho ra kết quả không khác gì ví dụ ở trên cùng, rõ ràng
đây là một tính chất đặc biệt của Javascript.
Trong trường hợp này, myFunc đang tham chiếu đến một instance displayName được tạo ra khi
chạy makeFunc. Instance của displayName sẽ duy trì lexical environment, biến name sẽ vẫn tồn
tại. Với lý do này, khi gọi hàm myFunc , giá trị biến name vẫn có và chuỗi "Mozilla" sẽ được
đưa vào hàm alert.
/* -------------------- */
- Currying là kỹ thuật mà cho phép chuyển đổi một function với nhiều tham số thành những
functions liên tiếp có một tham số.
- Viết thường:
function multiply(a, b, c) {
return a * b * c;
}
console.log( multiply(1,2,3) ); // 6
- Viết theo Currying:
function multiply(a) {
return (b) => {
return (c) => {
return a * b * c
}
}
}
console.log( multiply(1)(2)(3) ) // 6
- Viết theo Currying dùng arrow function:
const multiply = (a) => (b) => (c) => a * b * c;
https://topdev.vn/.../tim-hieu-currying-function-trong.../
/* -------------------- */
- Event loop:
- Javascript là single thread (đơn luồng) các lệnh trong javascript được thực hiện tuần tự từ trên
xuống dưới. Để xử lý bất đồng bộ, javascript sẽ đưa cho Web API xử lý sau khi Web API xử lý
xong thì đưa vào callback queue và khi callstack là empty thì 1 event loop sẽ đưa các callback
function trong callback queue lên execution stack và thực hiện tuần tự,..
- Callstack: nơi hàm được gọi, có cấu trúc ngăn xếp vào sau ra trước.
- Callback queue: hàm được Web API xử lý xong, thì sẽ được đưa vào hàng đợi này.
- Event loop: event loop sẽ đưa các callback function trong callback queue vào Callstack để thực
thi.
- Video hay nhất nói về event loop: https://www.youtube.com/watch?v=8aGhZQkoFbQ
- Trang web miêu tả quá trình event loop: http://latentflip.com/loupe/
/* -------------------- */
- Callback, Promise, Async/await: https://www.youtube.com/watch?v=fyYLkfmsFEA
- Callback: một function A được truyền vào một function B dưới dạng tham số. Tới một thời
điểm nào đó, function A sẽ được function B gọi lại (callback). Function nào được truyền vào như
một tham số và được gọi sau đó sẽ có tên là callback function.
- Chúng ta sử dụng callback rất nhiều, các hàm onlick, setTimeout, get api,...
$('button').click(function() {
alert("The button was clicked.");
});
setTimeout(function() {
console.log( "I waited 1 second!");
}, 1000);
$.get('https://api.giphy.com/', function(data) {
$('#cat').attr('src', data.data.image_url);
});
- Callback đảm bảo code sẽ không hoạt động trước khi các code khác hoàn thành việc thực thi.
- Callback đảm bảo trình duyệt không bị đơ do blocking (trình duyệt phải chờ javascript xử lý
một tiến trình thì mới tiếp tục nên bị đơ), dùng vào trường hợp một tiến trình bất đồng bộ, ngay
khi tiến trình bất đồng bộ chạy xong, cho ra kết quả thì sẽ gọi lại hàm callback, callback nhận kết
quả để xử lý công việc tiếp theo; Trường hợp là dùng callback để xử lý event, đưa một hàm
callback vào để khi người dùng nhấn nút, hover chuột,.. thì sẽ gọi hàm callback đó để xử lý công
việc tiếp theo.
- Callback https://codepen.io/nnt25251325/pen/jOEmBPW?editors=1011
- Promise (ES6): là một đối tượng thể hiện cho sự hoàn thành hoặc thất bại của một tiến trình bất
đồng bộ. Dùng Promise sẽ tránh được việc callback hell (callback lồng nhau).
- Dùng Promise.all() để nối kết quả của các promise chạy song song, khi nào tất cả các promise
này chạy xong, thì hàng Promise.all() sẽ trả về kết quả của tất cả.
- Promise: https://codepen.io/huyhoangpham/pen/GMZgrq?editors=1010
- async/await (ES7): giúp code dễ đọc hơn, code nhìn như đồng bộ. Tuy nhiên, không nên lạm
dùng async await, nếu các promise bắt buộc phải chờ nhau, kết quả của promise này phụ thuộc
vào kết quả của promise trước đó thì mới dùng async await, còn các promise chạy song song, ko
phụ thuộc vào nhau thì nên dùng promise.
- Vì mỗi lần gọi tới hàm await (các promise) sẽ đợi cho đến khi hàm await trước đó kết thúc. Các
await sẽ đợi và thực hiện tuần tự từng cái một, mất thời gian đợi.
Ví dụ: callback hell:
getData(function(a){
getMoreData(a, function(b){
getMoreData(b, function(c){
getMoreData(c, function(d){
getMoreData(d, function(e){
...
});
});
});
});
});
Ví dụ: promise:
getData()
.then(getMoreData)
.then(getMoreData)
.then(getMoreData)
.then(getMoreData)
.then((result) => {
// do something
})
.catch((err) => {
console.error(err);
})
Ví dụ: async/await:
async function doGreatThing () {
try {
const firstData = await getData();
const secondData = await getData(firstData);
const thirdData = await getData(secondData);
const saveResults = await Promise.all([
saveData(firstData);
saveData(secondData);
saveData(thirdData);
]);
} catch (err) {
console.error(err);
}
}
/* -------------------- */
Local storage:
- Lưu trữ trên client, lưu mãi mãi, trừ khi xóa nó hoặc xóa dữ liệu trình duyệt.
- Lưu trữ lớn hơn, được 5MB.
- Dữ liệu không được gửi lên Server.
- Dùng lưu các thông tin cơ bản của người dùng.
Session:
- Lưu trữ trên client, bị mấy khi đóng tab, đóng trình duyệt.
- Lưu trữ nhiều hơn cookie.
- Dữ liệu không được gửi lên Server.
- Dùng lưu các thông tin cơ bản của người dùng.
Cookie:
- Lưu trữ trên client, có thời gian sống.
- Lưu trữ tối đa 4KB.
- Dữ liệu được gửi lên Server.
- Dùng để server biết được client này đã được xác thực thành công hay chưa.
/* -------------------- */
Hàm thuần khiết (Pure function)
- Hàm luôn trả về cùng một kết quả nếu được truyền vào các tham số không đổi. Nó không hề
phụ thuộc vào bất kỳ trạng thái hoặc dữ liệu nào, cũng như những sự thay đổi trong khi chương
trình đang được chạy. Nó chỉ phụ thuộc vào các tham số đầu vào của nó.
- Hàm này không tạo ra bất kỳ ảnh hưởng nào đến các đối tượng khác , chẳng hạn như các
request, input, output hoặc data mutation. Đó là định nghĩa của một hàm thuần khiết. Nếu nó
thỏa mãi 2 điều kiện trên thì nó chính là một hàm thuần khiết. Bạn có thể đã tạo ra rất nhiều hàm
thuần khiết trong quá khứ mà không hề nhận ra.
Ví dụ pure function: Với mỗi price thì luôn trả về 1 giá trị duy nhất.
function priceAfterTax(price) {
return (price* 0.20) + price;
}
Ví dụ không phải pure function: Với mỗi price, còn phụ thuộc vào tax thì trả về các giá trị khác
nhau.
const tax = 20;
function calculateTax(price) {
return (price * (tax/100)) + price;
}
/* -------------------- */
Ứng dụng single page application (SPA):
SPA có một trang gốc và trong trang gốc đó, chúng ta có thể tải nhiều trang con.
SPA chỉ load phần trang cần thiết chứ không tải lại toàn bộ trang.
Với cách server trả data dạng JSON, phía server sẽ giảm được bớt tài nguyên.
Giúp user cảm nhận việc sử dụng website nhanh hơn.
- Angular, ReactJS, VueJS có cái hay ở chỗ có áp dụng việc xử lý trên DOM ảo nên tốc độ xử lý
nhanh; code được tách thành nhiều component, gom code html, css, xử lý js nằm trong một
component nên cách viết code tiện hơn, có thể tái sử dụng, việc quản lý và bảo trì cũng dễ dàng
hơn.
/* -------------------- */
Immutability: Tính bất biến của array và object.
Cần kiểm soát tốt tính bất biến của biến, nếu không thì rất dễ gây ra bug, do biến bị biến đổi qua
các hàm mà ta không biết.
Đảm bảo tính bất biến: dùng concat, toán tử 3 chấm rest params, dùng Object.assign({},
my_object)
Ví dụ:
const a = [1, 2, 3];
const b = a.push(4);
console.log(a); // Kết quả: [1, 2, 3, 4]
console.log(b); // Kết quả: [1, 2, 3, 4]
a bị biến đổi.
Ví dụ:
const a = [1, 2, 3];
const b = a.concat([4]);
console.log(a); // Kết quả: [1, 2, 3]
console.log(b); // Kết quả: [1, 2, 3, 4]
a không bị biến đổi
Nếu muốn thêm 4 vào đầu a thì dùng: const b = [4].concat(a);
Ví dụ:
const a = [1, 2, 3];
const b = [...a, 4];
console.log(a); // Kết quả: [1, 2, 3]
console.log(b); // Kết quả: [1, 2, 3, 4]
a không bị biến đổi
Nếu muốn thêm 4 vào đầu a thì dùng: const b = [4, ...a];
Ví dụ:
const a = { name: 'Nam', age: 16 };
const b = Object.assign({}, a);
b.age = 18;
console.log(a); // Kết quả: { name: 'Nam', age: 16 }
console.log(b); // Kết quả: { name: 'Nam', age: 18 }
a không bị biến đổi
Object.assign là shadow copy, nên chỉ đảm bảo được tính bất biến của các thuộc tính ở cấp đầu
tiên, các thuộc tính lồng nhau sâu bên trong thì không.
/* -------------------- */
- Truy cập tới các thuộc tính của object bằng dấu chấm (vd: obj.a) hay dấu ngoặc (vd: obj["a"]).
+ Dấu ngoặc hữu dụng nếu bạn có một tên thuộc tính có ký tự đặc biệt trong nó, obj["hello
world!"].
+ Dấu ngoặc cũng hữu dụng nếu bạn muốn tiếp cận một thuộc tính nhưng tên được lưu trữ ở biến
khác:
var obj = {
a: "hello world",
b: 42
};
var b = "a";
obj[b]; // "hello world"
obj["b"]; // 42
/* -------------------- */
- Hàm vô danh và hàm được định danh (hàm được đặt tên) :
Vô danh:
setTimeout(function() {
console.log( "I waited 1 second!");
}, 1000);
Hàm có tên:
setTimeout(function timeoutHandler() {
console.log( "I waited 1 second!");
}, 1000);
/* -------------------- */
- Cách viết hàm thông thường:
function foo() {
var a = 3;
console.log(a);
}
foo(); // 3
- Cách viết biếu thức hàm tức (IIFE) thì: (function foo() { ... })()
Hoặc có một cách viết khác như này: (function() { ... }())
(function foo() {
var a = 3;
console.log( a ); // 3
})();
- Biến tấu khác của IIFE cũng hay thấy là sử dụng sự kiện trong
sự kiện, chỉ gọi hàm, và truyền vào tham số.
var a = 2;
(function IIFE( global ) {
var a = 3;
console.log( a ); // 3
console.log( global.a ); // 2
})( window );
console.log( a ); // 2
/* -------------------- */
XHTML là viết tắt của EXtensible HyperText Markup Language (Ngôn ngữ HTML mở rộng)
XML là ngôn ngữ đánh dấu nơi tài liệu phải được viết (đánh dấu) chuẩn xác.
Bằng cách kết hợp những thế mạnh của HTML và XML, XHTML được phát triển.
Các phần tử phải lồng nhau đúng cách, phải được đóng, phải được viết bằng chữ in thường.
Tên thuộc tính phải được viết bằng chữ in thường, các giá trị của thuộc tính phải được cho vào
dấu ngoặc kép.
Ví dụ:
<p>Đây là văn bản
Viết như này mới đúng:
<p>Đây là văn bản</p>
Ví dụ:
<span><i>Lorem</span></i>
Viết đúng:
<span><i>Lorem</i></span>
Ví dụ:
<br>
<hr>
<img src=”happy.gif” alt=”Happy face”>
Viết đúng:
<br />
<hr />
<img src=”happy.gif” alt=”Happy face” />
Ví dụ:
<DIV>Đây là văn bản</DIV>
Viết đúng:
<div>Đây là văn bản</div>
Ví dụ:
<input TYPE=”checkbox” name=”vehicle” value=”car” checked />
Viết đúng:
<input type=”checkbox” name=”vehicle” value=”car” checked=”checked” />
/* -------------------- */
1 số tính năng mới trong JS ES5 và ES6:
- String template (`${item}`)
- let và const.
- Default parameter - Giá trị mặc định cho tham số:
const add = (num1 = 0, num2 = 0) => num1 + num2;
- Arrow function.
- Có khai báo class như OPP.
- Promise để xử lý mấy cái callback hell.
- Rest parameter - Toán tử 3 chấm để lấy những tham số còn lại.
function showName(firstName, lastName, ...props) {}
- Spread syntax - Toán tử 3 chấm.
const arr = [3, 8, 1];
alert( Math.max(...arr) );
- Hàm Array.find()
- Hàm Array.findIndex()
- Exponentiation (**) - Toán tử lũy thừa.
console.log(4 ** 2) // 16
console.log(4 ** 3) // 64
https://code4shares.wordpress.com/.../1-so-tinh-nang-moi.../
https://www.bravebits.co/tai-sao-lai-co-es6/
https://www.w3schools.com/js/js_es6.asp
/* -------------------- */
One way binding:
v-bind gán giá trị biến message vào thuộc tính value của thẻ <input>
<input type="text" v-bind:value="message">
{{ message }} // Dù có nhập vào ô input để thay đổi giá trị của message thì dòng này vẫn chỉ in
ra giá trị: Xin chào, tôi là Vue.js
new Vue({
el: '#app',
data: {
message: 'Xin chào, tôi là Vue.js'
}
})
Two way binding:
v-bind gán giá trị biến message vào thuộc tính value của thẻ <input>.
v-on lắng nghe sự kiện keyup là khi gõ văn bản vào ô nhập liệu thì nó sẽ gán text vừa nhập vào
biến message.
<input type="text" v-bind:value="message" v-on:keyup="message = $event.target.value">
{{ message }} // Khi nhập vào ô input để thay đổi giá trị của message thì dòng này sẽ thay đổi
theo giá trị đã nhập.
new Vue({
el: '#app',
data: {
message: 'Xin chào, tôi là Vue.js'
}
})
v-model (binding 2 chiều): Thực ra v-model là cú pháp ngắn gọn cho cú pháp tổng hợp cả v-bind
và v-on ở trên
<input type="text" v-model="message">
/* -------------------- */
Các thẻ Meta cần thiết cho SEO
Meta Title:
<title>tiêu đề</title>
Meta Description:
<meta name=”description” content=”mô tả” />
Meta Robots:
<meta name=”robots” content=”noodp,index,follow” />
Meta Revisit After:
<meta name=’revisit-after’ content=’1 days’ />
Meta Content Language:
<meta http-equiv=”content-language” content=”vi” />
Meta Content Type:
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
Link Favicon:
<link href=”favicon.ico” rel=”shortcut icon” type=”image/x-icon” />
https://seongon.com/.../the-meta-can-thiet-cho-seo.html
/* -------------------- */
Độ ưu tiên của bộ chọn CSS:
a = Inline style
b = Using id (#)
c = Using classes (.) and pseudo-classes
d = Using HTML tags
Formula: 1000*a + 100*b + 10*c + d
Ví dụ:
ul li { ... } /* Rank: 2 (1 + 1) */
.red { ... } /* Rank: 10 */
#myID { ... } /* Rank: 100 */
#myID .red { ... } /* Rank: 110 (100 + 10) */
#myID .red div > ul { ... } /* Rank: 112 (100 + 10 + 1 + 1) */
#myID .red div li:first-child { ... } /* Rank: 114 (100 + 10 + 1 + 1 + 2) */
/* -------------------- */
- Object.assign(): Copy an object, clone từ một object khác, và nối hai hay nhiều object lại với
nhau.
- Shallow copy là sử dụng Object.assign() và Spread Operator (toán tử 3 chấm) để copy object:
const clone = Object.assign({},obj)
const clone = {...obj}
- Deep copy là sử dụng JSON.parse() và JSON.stringify():
const clone = JSON.parse(JSON.stringify(obj))
=> Shallow copyingchỉ copy những giá trị nông, nghĩa là nó chỉ sao chép các giá trị đối tượng
bình thường nhưng các giá trị lồng nhau vẫn sử dụng chung reference address đến một đối tượng
ban đầu.
/* -------------------- */
- Sự khác biệt thực tế duy nhất giữa các vòng lặp này là liệu điều kiện được kiểm tra trước lần
lặp đầu tiên (while) hay sau lần lặp đầu tiên (do... while).
/* -------------------- */
Toán tử && dùng để làm điều kiện hiển thị element trong reactjs
{ this.state.list.length && <div className="box-list"></div> }
{ !this.state.list.length && <div className="box-notice">No data</div> }
Giải thích:
true && 8 // kết quả là 8
false && 8 // kết quả là false
true && true && 8 // kết quả là 8
true && 8 && false && 12 // kết quả là false
- Nếu vế thứ nhất đúng, thì trả về vế thứ 2.
- Nếu vế thứ nhất sai, thì trả về về thứ nhất.
- Nếu có nhiều vế đúng, thì sẽ trả về vế đúng cuối cùng.
- Nếu có 1 vế false bất kì, thì sẽ trả về false.
/* -------------------- */
script async và defer:
<script src="script.js">
Với thẻ script không có thuộc tính gì khác thì HTML file sẽ được parse cho đến khi gặp phải thẻ
script, đến lúc này thì quá trình parse sẽ tạm dùng và để fetch script file về (nếu là external file),
sau đó execute những code script này, sau đó mới tiếp tục lại quá trình parse html
<script async src="script.js">
Với thẻ script có thuộc tính async, khi quá trình parse html gặp phải script này, nó sẽ vẫn tiếp tục
parse html cho đến khi script này được download xong, thì quá trình parse html mới tạm dừng để
execute những code script này, sau đó lại tiếp tiếp quá trình parse html
<script defer src="script.js">
Với thẻ script có thuộc tính defer, quá trình parse html sẽ không bị dừng lại mà parse cho đến khi
hoàn thành, quá trình download các script file được tiến hành song song, và cuối cùng thì sẽ
execute những script code này khi html đã parse xong.
-Nếu script là 1 module tách biệt, không phụ thuộc vào script nào khác thì nên sử dụng async cho
load và execute với trang luôn
-Nếu script phụ thuộc vào script khác, hoặc bị script khác phụ thuộc, thì nên dùng defer, để load
và execute theo thứ tự
-Nếu script nhỏ và các script khác phụ thuộc vào nó, thì cho load inline và không cần async hay
defer
https://viblo.asia/.../javascript-async-va-defer...
/* -------------------- */
- XSS: chèn các đoạn script chứa mã độc vào database để chiếm quyền. Chẳng hạn gửi một đoạn
mã vào form chat: <script>alert(document.cookie)</script>
hacksplaining.com/exercises/xss-stored
Phòng chống:
+ Escape dynamic content là lọc dữ liệu đưa vào, encode thành các ký tự HTML entity encode (<
thành &#60, > thành &#62);
+ Whitelist values là chỉ cho phép một số tag được hiển thị, còn lại thì chặn hết;
+ Implement a content-security policy là trên server sẽ gửi request có header là Content-
Security-Policy: script-src 'self' nguon_trang_web => chỉ cho chạy script từ cái nguồn
nguon_trang_web. Hoặc thêm thẻ meta vào thẻ head <meta http-equiv="Content-Security-
Policy" content="script-src 'self' nguon_trang_web">
/* -------------------- */
- CSRF: Cross-Site Request Forgery: là kỹ thuật tấn công bằng cách sử dụng quyền chứng thực
của người dùng đối với một website, dựa vào mượn quyền trái phép. Chẳng hạn khi gửi 1 request
lên server, đính kèm cookie vào request này để server xác thực người dùng này. Kẻ tấn công dụ
người dùng click vào 1 đường link, vô tình gửi request cùng cookie xác thực, mặc dùng ko phải
người dùng cần xác thực mà server vẫn xác thực vì đúng cookie.
hacksplaining.com/exercises/csrf
Phòng chống:
+ Dùng anti forgery token là dùng một mã ngẫu nhiên đưa vào input hidden để server xác thực
được, mã này kẻ tấn công ko biết);
+ Dùng SameSite=Strict, những request tới từ những trang khác thì đều bị browser gỡ hết
cookie.
/* -------------------- */
- VueX
State: một object chứa dữ liệu của store.
Getter: giống như một bộ lọc cho phép truy cập và sàng lọc dữ liệu, các component sẽ gọi đến
các getter để lấy dữ liệu từ store.
Mutation: nơi chúng ta thực hiện các thay đổi state, set lại state ở đây.
Action: component dùng dispatch để gọi đến các action, action nhận dữ liệu từ component,
action gọi đến mutation để commit các thay đổi, đưa dữ liệu cho mutation.
/* -------------------- */
Click bên trong vùng có click: Dùng stopPropagation để ngăn chặn sự lan rộng của sự kiện hiện
tại tới thằng khác.
Ví dụ:
<div class="item">
<div class="preview-img">Preview Image</div>
</div>
Khi click vào item thì sẽ đi đến trang chi tiết, nhưng sẽ có 1 nút preview-img nằm trong vùng
item, khi click vào nút này sẽ mở popup xem trước ảnh của item.
Nếu để mặc định, click vào nút preview-img vẫn sẽ đi đến trang item.
$('.item').on('click', function(e) {
console.log('Go to detail');
});
$('.preview-img').on('click', function(e) {
e.preventDefault();
e.stopPropagation();
console.log('Preview Image');
});
/* -------------------- */
Viết sleep dùng trong async await:
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
Cách dùng: await sleep(1000)
/* -------------------- */
Số mũ trong javascript: 3^5 viết là 3**5
/* -------------------- */
Viết hàm để chạy được:
duplicate([1,2,3,4,5]); // [1,2,3,4,5,1,2,3,4,5]
Giải:
function duplicate(array) {
return array.concat(array);
}
console.log(duplicate([1,2,3,4,5])); // [1,2,3,4,5,1,2,3,4,5]
/* -------------------- */
Đoạn code dưới đây sẽ in ra giá trị gì?
console.log(typeof typeof 1);
Giải: Giá in ra sẽ là string.
Vì: typeof 1 sẽ return ra "number", typeof "number" sẽ return ra `string
/* -------------------- */
Giá trị của i in ra là bao nhiêu?
for (var i = 0; i < 10; i++) {
}
console.log(i);
Giải: là 10
Biến i đang dùng var để khai báo, vì vậy biến i vẫn nằm trong scope ngay cả sau khi vòng lặp for
đã hoàn thành, giữ lại giá trị cuối cùng của nó sau khi thoát khỏi vòng lặp. Vậy nên để tránh lỗi,
ta nên dùng let: for (let i = 0; i < 10; i++) {}
/* -------------------- */
Giá trị của a in ra là như nào?
function run(){
a = 1;
}
run();
console.log(a);
Giải: Là 1
Nhờ hành động hoisting, javascript tự động khai báo biện a lên đầu và đoạn code đó trở thành
như sau:
var a;
function run(){
a = 1;
}
run();
console.log(a);
/* -------------------- */

You might also like