Skip to content
youhoc
  • Pages
    • Home
    • Modern App Guidelines
    • Linux
      • Day 1: Linux Distributions & Navigation
      • Day 2: User Management
      • Day 3: File Permission & Ownership
      • Day 4: Package Management
      • Day 5: Services Management
    • Javascript
      • JS The Weird Part
        • Execution Context
        • Types & Operators
        • icon picker
          Objects & Functions
        • Error Handling & Strict Mode
        • Typescript, ES6, Tra
      • Modern JS
        • JS in the Browser
        • Data Storage JSON
        • Modern JS
        • Advanced Objects & Methods
        • Webpack & Babel
        • Async
      • jQuery
        • In-depth Analysis of jQuery
      • React-ready JS
        • Arrow Function
        • Template Literals
        • Logical AND, OR, Ternary, Nullish Operators
        • Destructuring & Rest Operator
        • Array Method
        • Immutability and Spread Operator
        • Promises, Async/Await, Callback
    • PHP
      • gruntJS
      • composer
      • MySQL
    • Docker
      • Container Basics
      • Container Networking
      • Container Image
      • Container Volume & Persistent Data
      • Dockerfile
      • Docker Compose
      • Docker Registry
    • Node.js
      • 1. Installing & Exploring
      • 2. Core Modules
      • 3. Get User Input
      • File System & Input Arguments
      • 5. Express Web Server
      • 6. Deploy to Heroku & Github
      • Authentication
      • 7. Databases
      • 8. Rest API
    • ReactJS
      • React from Andrew
        • Summary from Next
        • 1. Basics
        • 2. React Components
        • 3. Webpack
        • 4. Styling with SCSS
        • 5. React Router
        • 6. React Hook
      • Modern React From The Beginning
        • Intro to JSX
        • Vite Build Tools
        • Basic Component Creation
        • Component State
        • Props & Component Composition
        • useState with Inputs & Form Submission
        • useEffect, useRef & Local Storage
        • Async / Await and Http Request in React
        • React Router: Declarative Mode
        • ContextAPI
        • React Router: Framework Mode
          • File-routing & HTML Layouts
          • Server-side Data Query
          • Links & Navigation
          • Loaders
    • Typescript
      • Type User vs UserProp
    • Payload CMS

Objects & Functions

Object can contain:
name / value
other objects
functions
Create an object:
// reserve in memory
var person = new Object();

// set properties
person["name"] = "Tony";
person["country"] = "Vietnam";

// access object properties
console.log(person)
console.log(person.name)
console.log(person.country)

var nameProperty = "name";
console.log(person["nameProperty"])

// set other object inside object
person.address = new Object();
person.address.street = "Yen Do";
person.address.city = "Ho Chi Minh";

// access object inside object
console.log(person.address.street);
console.log(person["address"]["street"];
Thường chỉ nên dùng DOT để truy cập giá trị của Object
console.log(person.name)
Chỉ nên dùng STRING ARRAY khi cần truy cập giá trị bằng tên động
var nameProperty = "name";
console.log(person["nameProperty"])
Object Literals
// new Object(), reserve in memory
var person = {};

var Tony = {
name: 'Tony',
country: 'Vietnam',
address: {
street: 'Yen Do',
city: 'Ho Chi Minh'
}
};

// function to call an object
function greet(person) {
console.log('hi ' + person.name)
}

greet(Tony); // 'hi Tony'

// create object on the fly
greet( {name:'Mary',country:'US'} ); // 'hi Mary'
JSON & Object Literals
// object
var objectName = {
name: 'Tony',
country: 'Vietnam',
address: {
street: 'Yen Do',
city: 'Ho Chi Minh'
}
};

// convert to JSON string
console.log( JSON.stringlify(objectName) )
// JSON
{
"name": "Tony",
"country": "Vietnam",
"address": {
"street": "Yen Do",
"city": "Ho Chi Minh"
}
}
// convert string to JSON
var jsonVar = JSON.parse( '{ "street": "Yen Do", "city": "Ho Chi Minh"}' )

Function & Object Literals

Functions are Objects
First-class Functions: everything you can do with other types, you can do with funtion.
Assing them to var, pass around, create on the fly
Function cũng có:
property: name / values
objects
function con
Function có thêm:
invocable (có thể gọi được)
có code bên trong
Function Expression: một đoạn mã trả lại một giá trị
Function Statement: một đoạn mã chỉ thực hiện một hành động (so sánh IF hay in ra log)

By Value & By Reference

MUTATE vs NEW OBJECT

‘this’

Seem like a bug in JS, but this is an unusual scenario:

Arrays

arguments and SPREAD

là những gì bạn truyền vào bên trong một function
SPREAD
Function Overloading
Một cách hay để chia nhỏ function, không truyền quá nhiều arguments
Lưu ý Syntax Parser
Nên tự hết dòng bằng dấu chấm phẩy, vì nếu để JS tự thêm chấm phẩy thì sẽ có nhiều bug khó track
Whitespace: xuống hàng, spacing, tabbing

Immediate Invoking Function

Phong cách viết này rất dễ gặp trong các framework nổi tiếng say này.
ĐỂ TÁCH BIỆT NHỮNG FILE JS CÓ BIẾN RIÊNG, CHẠY ĐỘC LẬP, TRẢ VỀ KẾT QUẢ XONG RỒI BIẾN MẤT
KHÔNG ẢNH HƯỞNG ĐẾN NHỮNG FILE JS TRÊN HAY DƯỚI, không ảnh hưởng đến Global Object
có thể tùy chọn access những biến global nếu thích, nhưng sẽ an toàn
Tình huống kinh điển:

Closures

Ngay cả khi 1 hàm đã chạy xong, thì những biến và hàm bên trong hàm đó vẫn còn hiệu lực
gọi là closure:
image.png
Ngay cả khi greet() đã chạy xong thì các biến và hàm bên trong greet vẫn còn hiệu lực.
Tình huống kinh điển: chắc để tạo ra 1 mớ hàm
Nếu muốn lưu biến i chạy vòng lặp và thu gọn các dòng code:
sử dụng IIFE
sử dụng let trong ES6
Tạo ra factory function
image.png
Closure & Callback
callback là ứng dụng của closure
call(), apply(), bind()
Function Borrowing
Mượn hàm của object này, chạy cho object khác
Function Currying
Copy hàm với một bộ giá trị param chỉ định
Tổng kết:
bind có thể thực hiện với object để thay đổi bối cảnh ‘this’
bind có thể thực hiện với ‘this’ để thay đổi param mặc định (’this’ không đổi)
bind không thực thi, call và apply thực thi

Functional Programming

Code đẹp để tạo ra 1 hàm xử lý mảng
// ví dụ, có 1 mảng, map thành 1 mảng mới với một điều kiện nhất định
var arr1 = [1,2,3];

// ví dụ muốn xử lý mảng rồi tạo ra 1 mảng mới
var arr2 = [];

// đây là cách thường làm
for(var i=0; i < arr1.length; i++) {
// map giá trị của mảng 2 tương ứng với mỗi giá trị của mảng 1...
arr2.push(
// sẽ bằng giá trị mảng 1 nhân với 2
arr1[i] * 2;
)
}

console.log(arr1);
console.log(arr2);

// cách này có hạn chế là phải hard-code hàm
// không thể linh động thay đổi hàm, giá trị cần mutate mảng
// CÁCH XỊN LEVEL 1, viết một hàm first-class, sử dụng những gì đã học
function mapForEach(arr, fn) {
var newArr = [];
// đối với mỗi giá trị của mảng truyền vào
for (var i=0; i < arr.length; i++) {
// tạo một mảng mới...
newArr.push(
// với các giá trị của hàm được truyền vào
fn(arr[i])
)
};
// trả lại mảng mới
return newArr;
}

var arr1 = [1,2,3];

// trả lại giá trị như hàm cũ
var arr2 = mapForEach(arr1, function(item) {
return item * 2;
});

// có thể truyền mọi thứ, từ công thức đến điều kiện boolean [false, false, true]
var arr3 = mapForEach(arr1, function(item) {
return item > 2;
});
// LEVEL MAX, kết hợp với bind() để đơn giản hóa việc gọi hàm hơn nữa

// giả dụ, nếu cần tạo ra 1 hàm so sánh mảng với giá trị được truyền vào (thay vì 2)
var checkPastLimit = function(limiter, item) {
return item > limiter;
}
// dùng bind() để cố định param 'limiter' là 2 cho mỗi giá trị của arr1 ('this')
// sau bind(this, 2) thì chính là tương đương (limiter = 2, item)
var arr4 = mapForEach(arr1, checkPastLimit.bind(this, 2));

// hàm ở trên vẫn còn dư 'this', bây giờ làm cách nào bỏ 'this' luôn
var checkPastLimitSimplified = function(limiter) {
// 3. return object trả lại 1 hàm, với 'this'item' và limiter được truyền vào
return function(limiter, item) {
return item > limiter;
}.bind(this, limiter);
// 1. nhận limiter truyền vào
// 2. bind vào return object với 'this' và limiter
};

var arr5 = mapForEach(arr1, checkPastLimitSimplified(2));
Đọc thêm để hiểu về cách khái niệm cao cấp của functional programming
Có nhiều ví dụ tương tự như ví dụ bên trên
Một mớ hàm xử lý mảng được viết sẵn, nên đọc để học rồi xài

Inheritance (không hay)

Một object thừa hưởng các thuộc tính và hàm thì object khác
classical inheritance
propotypal inheritance: easy, flexible, extensible
// old, slow-down way to access, DON'T DO
var person = {
name: 'default',
getFullName: function () {
return 'hello' + this.name;
}
}

var tony = {
name: 'Tony'
}

// tony to inherit person method, property
tony.__proto__ = person;

// will look for 'name' in primary object first
console.log( tony.getFullName() )
object a{} has default a.__proto__.method (toString,...)
function b() has default b.__proto__.method (apply, call, bind...)
array c[] has default c.__proto__.method (push, pop...)
// extend is feasible through refelction
//
for (var prop in tony) {
// kiểm tra các prop của object
if(tony.hasOwnProperty(prop)) {
console.log(prop + ': ' + tony[prop])
}
}

var hanah = {}
var bambi = {}

// hợp nhất 3 object bằng hàm underscore.js library mà không cần replace __proto__
_.extend(tony, hanah, bambi);

Builidng Objects

Cách xây dựng 1 object bằng Function Constructor
// function constructor
// có cách mới để tạo object, cách cũ này sẽ biến mất, nhưng vẫn nên hiểu
function Person(firstname, lastname) {
console.log(this);

// 'this' points to a new empty object
this.firstname = firstname;
this.lastname = lastname;

// this will cost memory space, than creating a prototytpal method
this.getFullName = function () {}

console.log('This function is invoked.');
}

// prototypal method added to fucntion BEFORE creating object
// this will save memory space, than putting method directly into objects
Person.prototype.getFullName = function() {
return this.firstname + ' ' + this.lastname;
}

// new = empty object
// return anything in the function 'Person' into an object
var john = new Person('John', 'Doe');
console.log(john);

// nếu không có 'new' sẽ bị undefined
var jane = new Person('Jane', 'Doe');
console.log(jane);

// prototypal method added to fucntion AFTER creating object, still work
Person.prototype.getFormalFullName = function() {
return this.lastname + ', ' + this.firstname;
}

console.log(john.getFormalFullName());
Một số object mặc định của JS
// tạo ra 1 object với giá trị "hello"
var a = new String("hello")

// tìm letter 'o' trong chuỗi
// String.prototype.indexOf(3)
a.indexOf("o")

// tạo ra 1 object với giá trị 3
var a = new Number(3)

// chuyển thành số
// Number.prototype.toFixed()
a.toFixed()

var a = new Array();
Nếu muốn một library xử lý Date, cân nhắc dưới đây:
CẨN THẬN VỚI MẤY CÁI HÀM BUILT-IN NÀY, HIỂU THÔI CHỨ ĐỪNG CÓ XÀI.
Object.create
literal syntax
function constructor
Object.create
tạo ra 1 object mẫu, với default properties và methods
tạo ra nhiều object khác từ object mẫu
properties thay đổi, sẽ ưu tiên các giá trị mới hơn
method vẫn giữ nguyên
var person = {
firstname: 'Default',
lastname: 'Default',
greet: function() {
return 'Hi ' + this.firstname;
}
}

var john = Object.create(person);
john.firstname = 'John';
john.lastname = 'Doe';
console.log(john);
Nếu sử dụng browser cũ, thì Object.create sẽ chưa hỗ trợ
// polyfill
if (!Object.create) {
Object.create = function (o) {
// chỉ chấp nhận 1 args
if (arguments.length > 1) {
throw new Error('Object.create implementation only accepts the first parameter.');
}
function F() {}
F.prototype = o;
return new F();
};
}
Thêm 1 cách để tạo Object bằng Classes trong ES6
Nếu sử dụng ES6, có thêm Classes:
// class = function constructor
Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.