Thứ Năm, 1 tháng 4, 2021

Javascript nâng cao

 Docs: https://www.w3schools.com/js/js_intro.asp


## Object Prototypes
https://www.w3schools.com/js/js_object_prototypes.asp

- All JavaScript objects inherit properties and methods from a prototype:
Date objects inherit from Date.prototype
Array objects inherit from Array.prototype

Có rất nhiều Object Prototypes được viết sẵn như Date, Array, Object, Json...
Ngoài ra cũng có thể tự viết các Object Prototypes tùy mục đích sử dụng

- Example
<script>
function Person(first, last, age, eye) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eye;
}
Person.prototype.name = function() {
return this.firstName + " " + this.lastName
};
var myFather = new Person("John", "Doe", 50, "blue");
document.getElementById("demo").innerHTML = "My father is " + myFather.name();
</script>

## inheritance
https://www.w3schools.com/js/js_object_classes.asp

<script>
class Car {
constructor(brand) {
this.carname = brand;
}
present(x) {
return x + ", I have a " + this.carname;
}
}
mycar = new Car("Ford");
document.getElementById("demo").innerHTML = mycar.present("Hello");
</script>
- Static Methods
class Car {
constructor(brand) {
this.carname = brand;
}
static hello() {
return "Hello!!";
}
}
Cách gọi: Car.hello();
- Inheritance
<script>
class Car {
constructor(brand) {
this.carname = brand;
}
present() {
return 'I have a ' + this.carname;
}
}

class Model extends Car {
constructor(brand, mod) {
super(brand); // gọi đến constructor của parent
this.model = mod;
}
show() {
return this.present() + ', it is a ' + this.model;
}
}

mycar = new Model("Ford", "Mustang");
document.getElementById("demo").innerHTML = mycar.show();
</script>
- Getters and Setters
class Car {
constructor(brand) {
this._carname = brand;
}
get carname() {
return this._carname;
}
set carname(x) {
this._carname = x;
}
}

mycar = new Car("Ford");
mycar.carname = "Volvo";
document.getElementById("demo").innerHTML = mycar.carname;
- Hoisting
không giống với function, class trong javascript không được lưu trữ
Nên cần phải khai báo class trước
==>

class Car {
constructor(brand) {
this.carname = brand;
}
}
//Now you can use the class:
mycar = new Car("Ford")

## event delegation (sử dụng addEventListener)
https://medium.com/@bretdoucette/part-4-what-is-event-delegation-in-javascript-f5c8c0de2983

List events: change, click, mouseover, mouseout, keydown, load....

<button id="buttonId">Click me</button>

<script>
document.getElementById('buttonId')
        .addEventListener('click', () => console.log('Clicked!'));
document.getElementById('buttonId').addEventListener('click', () => {
console.log('Body click event in capture phase');
}, true);
document.getElementById('buttons')
.addEventListener('click', event => { // Step 2
if (event.target.className === 'buttonClass') { // Step 3
console.log('Click!');
}
});
</script>

## getElementsByClassName
<div id="buttons">
<button class="buttonClass">Click me</button>
<button class="buttonClass">Click me</button>
<!-- buttons... -->
<button class="buttonClass">Click me</button>
</div>
<script>
const buttons = document.getElementsByClassName('buttonClass');
for (const button of buttons) {
button.addEventListener('click', () => console.log('Clicked!'));
}
</script>
## forEach
const checkBoxes = document.querySelectorAll(‘input’)
checkBoxes.forEach(input => input.addEventListener(‘click’, ()=> alert(‘hi!’)))

## querySelectorAll
const checkBoxes = document.querySelectorAll(‘input’)
checkBoxes.forEach(input => input.addEventListener(‘click’, ()=> alert(‘hi!’)))
## querySelector
const characterList = document.querySelector('.characters');
characterList.addEventListener('click', toggleDone);
//Event Delegation
function toggleDone (event) {
if (!event.target.matches(‘input’)) return
console.log(event.target)
//We now have the correct input - we can manipulate the node here
}
## use strict
Khi một đoạn lệnh được khai báo use strict
thì tất cả các dòng code ở phía dưới dòng khai báo use strict sẽ được quản lý
một cách nghiêm ngặt hơn về cú pháp.

- use strict mode for alls in file
"use strict";
myFunction();
function myFunction() {
y = 3.14; // This will also cause an error because y is not declared
}
- Only use strict mode for a function
x = 3.14; // This will not cause an error.
myFunction();
function myFunction() {
"use strict";
y = 3.14; // This will cause an error
}
## Scope
Phạm vi mà có thể truy xuất đến biến hoặc hàm.

function outer() {
var outer_var = 2;
function inner() {
alert(outer_var);
}
inner();
}
outer(); // out put: 2

## Closures
Các function con bên trong function cha, chứa ngữ cảnh(context) của function cha, nên
có thể truy xuất vào tất cả những gì đang có trong function cha.

function outside(x) {
function inside(y) {
return x + y;
}
return inside;
}
fn_inside = outside(3);
result = fn_inside(5); // #=> 8
result1 = outside(3)(5); // #=> 8

-
function A(x) {
function B(y) {
function C(z) {
alert(x + y + z);
}
C(3);
}
B(2);
}
A(1); #=> 6

B tạo ra một cái closure chứa context của A, do đó B có thể access vào A's variable,
ở đây là x.
C tạo ra một cái closure chứa context của B
Vì B chứa context của A nên C cũng sẽ chứa context của A,
tức là C cũng access được vào biến x của A,
và cả biến y của B.

- Closure pitfalls
<li id="click">link 1 </li>
<li id="click">link 2 </li>
<li id="click">link 3 </li>

var add_the_handlers = function (nodes) {
var helper = function (i) {
return function (e) {
alert(i);
};
};
var i;
for (i = 0; i < nodes.length; i += 1) {
modes[i].onclick = helper(i);
}
};
nodes = document.getElementById("click");
add_the_handlers(nodes);

## Promises

Sử dụng cho các chức năng cần sử dụng hàng loạt các bất đồng bộ nối tiếp nhau.

Một `Object Promise` đại diện cho một giá trị ở thời điểm hiện tại có thể chưa tồn tại,
nhưng sẽ được xử lý và có giá trị vào một thời điểm nào đó trong tương lai.

Ví dụ như bạn tạo ra 1 Object Promise chứa giá trị sẽ response về từ một API.
Điều cốt lõi ở đây là dữ liệu sẽ chưa tồn tại ở thời điểm đối tượng Promise được tạo ra,
mà chỉ có thể truy cập sau khi có response từ web service.
Trong thời gian chờ lấy dữ liệu, Promise object sẽ đóng vai trò như một proxy cho dữ liệu.
Hơn nữa, bạn có thể đính các callback vào Promise object để thực hiện việc xử lý dữ liệu.
Các callback này sẽ chỉ thực hiện khi dữ liệu đã sẵn sàng.

- Promise API
if (window.Promise) { // Check if the browser supports Promises
console.log('Promise found');
var promise = new Promise(function(resolve, reject) {
var request = new XMLHttpRequest();
request.open('GET', 'http://api.icndb.com/jokes/random');
request.onload = function() {
if (request.status == 200) {
resolve(request.response); // we got data here, so resolve the Promise
} else {
reject(Error(request.statusText)); // status is not 200 OK, so reject
}
};
request.onerror = function() {
reject(Error('Error fetching data.')); // error occurred, reject the Promise
};
request.send(); //send the request
});
console.log('Asynchronous request made.');
promise.then(function(data) {
console.log('Got data! Promise fulfilled.');
document.getElementsByTagName('body')[0].textContent = JSON.parse(data).value.joke;
}, function(error) {
console.log('Promise rejected.');
console.log(error.message);
});
} else {
console.log('Promise not available');
}
- Nối nhiều Promise
Bạn có thể có nhiều thao tác bất đồng bộ cần xử lý.
Khi một thao tác trả về dữ liệu,
bạn sẽ bắt đầu một xử lý bất đồng bộ khác sử dụng một phần dữ liệu từ thao tác trước đó,
và cứ tiếp tục như vậy.

function getPromise(url) {
// trả về một Promise ở ddây
// gửi một request lấy dữ liệu từ một url (request bất đồng bộ)
// sau khi lấy về kết quả, xử lý promise với dữ liệu nhận được
}
var promise = getPromise('some url here');
promise.then(function(result) {
//chúng ta có dữ liệu của url 'some url here' ở đây
return getPromise(result); //và trả về một promise khác
}).then(function(result) {
//ở đây chứa kết quả promise vừa trả về ở trên và logic để xử lý dữ liệu cuối cùng
});
- Xử lý lỗi
promise.then(function(result) {
console.log('Got data!', result);
}).catch(function(error) {
console.log('Error occurred!', error);
});
OR
promise.then(function(result) {
console.log('Got data!', result);
}).then(undefined, function(error) {
console.log('Error occurred!', error);
});

## Ajax (use XMLHttpRequest hoặc fetch)
Có nhiều cách để sử dụng post data như là
truyền param theo dạng chuỗi 'orem=ipsum&name=binny'
hay truyền theo dạng FormData.

<div id="demo">
<h2>The XMLHttpRequest Object</h2>
<button type="button" onclick="loadDoc()">Change Content</button>
</div>
<script>
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML =
this.responseText;
}
};
xhttp.open("GET", "ajax_info.txt", true);
xhttp.send();
}
</script>
- POST
var http = new XMLHttpRequest();
var url = 'get_data.php';
var params = 'orem=ipsum&name=binny';
http.open('POST', url, true);
//Send the proper header information along with the request
http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(params);
- FormData

<form enctype="multipart/form-data" method="post" name="fileinfo">
...
</form>

var data = new FormData();
data.append('user', 'person');
data.append('pwd', 'password');
data.append('organization', 'place');
data.append('requiredkey', 'key');
var xhr = new XMLHttpRequest();
xhr.open('POST', 'somewhere', true);
xhr.onload = function () {
// do something to response
console.log(this.responseText);
};
xhr.send(data);
- fetch
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

Short & modern: fetch(form.action, {method:'post', body: new FormData(form)});

// Advance
const url = "http://example.com";
fetch(url, {
method : "POST",
body: new FormData(document.getElementById("inputform")),
// -- or --
// body : JSON.stringify({
// user : document.getElementById('user').value,
// ...
// })
}).then(
response => response.text() // .json(), etc.
// same as function(response) {return response.text();}
).then(
html => console.log(html)
);
- customise post function
function post(path, data, callback) {
"use strict";
var request = new XMLHttpRequest();
if (path === "") {
path = "/";
}
request.open('POST', path, true);
request.setRequestHeader('Content-Type',
            'application/x-www-form-urlencoded; charset=UTF-8');
request.onload = function (d) {
callback(d.currentTarget.response);
};
request.send(serialize(data));
}
post("", {orem: ipsum, name: binny}, function (response) {
console.log(respone);
})

## Json (use JSON.parse)

<script>
var txt = '{"name":"John", "age":30, "city":"New York"}'
var obj = JSON.parse(txt);
document.getElementById("demo").innerHTML = obj.name + ", " + obj.age;
</script>
- JSON From the Server
Truy xuất object: myObj.nam

// json_demo.txt: { "name":"John", "age":31, "pets":[ { "animal":"dog", "name":"Fido" },
    //    { "animal":"cat", "name":"Felix" }, { "animal":"hamster", "name":"Lightning" } ] }
<script>
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myObj = JSON.parse(this.responseText);
document.getElementById("demo").innerHTML = myObj.name;
}
};
xmlhttp.open("GET", "https://www.w3schools.com/js/json_demo.txt", true);
xmlhttp.send();
</script>
- Array as JSON
Truy xuất dạng array: myArr[0]

// [ "Ford", "BMW", "Audi", "Fiat" ]
<script>
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myArr = JSON.parse(this.responseText);
document.getElementById("demo").innerHTML = myArr[0];
}
};
xmlhttp.open("GET", "json_demo_array.txt", true);
xmlhttp.send();
</script>
- Convert a string into a date object
<script>
var text = '{"name":"John", "birth":"1986-12-14", "city":"New York"}';
var obj = JSON.parse(text);
obj.birth = new Date(obj.birth);
document.getElementById("demo").innerHTML = obj.name + ", " + obj.birth;
</script>
- Convert a string into a date object
<script>
var text = '{"name":"John", "birth":"1986-12-14", "city":"New York"}';
var obj = JSON.parse(text, function (key, value) {
if (key == "birth") {
return new Date(value);
} else {
return value;
}
});
document.getElementById("demo").innerHTML = obj.name + ", " + obj.birth;
</script>
- Convert a string into a function. Use `eval`
<script>
var text = '{"name":"John", "age":"function() {return 30;}", "city":"New York"}';
var obj = JSON.parse(text);
obj.age = eval("(" + obj.age + ")");
document.getElementById("demo").innerHTML = obj.name + ", " + obj.age();
</script>

Không có nhận xét nào:

Đăng nhận xét

Học lập trình web căn bản với PHP

Bài 1: Các kiến thức căn bản Part 1:  https://jimmyvan88.blogspot.com/2012/05/can-ban-lap-trinh-web-voi-php-bai-1-cac.html Part 2:  https://...