https://www.youtube.com/watch?v=X0ipw1k7ygU&list=PL4cUxeGkcC9haFPT7J25Q9GRB_ZkFrQAc&index=5
---
https://www.youtube.com/watch?v=4l3bTDlT6ZI&list=PL4cUxeGkcC9i5yvDkJgt60vNVWffpblB7
[TOC]
# Introduction
## primitive type
原型 Data Type
- string
- number
## JS 可以 暫時把 primitive type 包(warp)在Object 來調用他
```
name.length
10
```
明明不是obj 卻能類似像obj 方式使用
類似這樣
```
nameObj = new String(name)
```

# Object literal (直接定義Object)
Using objects could make variables and functions easier to manage; we could group them together in the variable we call "object"
## Encapsulation
```
var Meowhecker ={
email:"meowhecker@meowhecker.com", //encapsulation
name:"MeowHacker"
}
```
一種將抽象性函式介面的實作細節部份包裝、隱藏起來的方法
this 在obj 裡面會是 本身的obj
this 在object外面 就會試windows object
# Update Property
Object property can be access using ether the dot or curly braces.
curly braces for Object allow dynamic assign of values.

# Class

if we wish to avoid create similar objects, we can utilize class
prototype mode (class) 原型
crate multiple version of the same type of object
Class -> New instance (New Object)
## Construction function
The construction function is activated, when we crate the new instance or object.
The "this" keyword is used to refer to the current instance of a class.
this inside the class == new (Instance)
```javascript
//Lession 5 /class
class Account{
constructor(name,password){
//Hard code
//this.name = "mewohecker"
//this.password="mewohecker"
//dynamic
this.name=name
this.password=password
}
}
user1 = new Account('meowhecker','mewohecker123')
user2 = new Account('mewomewo','weommoew')
console.log(user1)
console.log(user2)
```

# Method Chaining
Method CHaining means the ability to invoke the function in a continuous sequence.
if we intend to use this trick, the function must to return the object; otherwise an undefined error will occur
```javascript
//Lession 5~6 /class
class Account{
constructor(name,password){
//Hard code
//this.name = "mewohecker"
//this.password="mewohecker"
//dynamic
this.name=name
this.password=password
this.score = 0
}
login(){
console.log(this.name,"just logged in")
return this;
}
logout(){
console.log(this.name, "just logged out")
return this;
}
methodChain(){
this.score++
console.log(this.name,'Now Score is ',this.score)
return this; //return the INstance for using the methodCHain.
}
}
user1 = new Account('meowhecker','mewohecker123')
user2 = new Account('mewomewo','weommoew')
console.log(user1)
console.log(user2)
user1.login().methodChain().methodChain().logout()
```


# Class Inheritance
class inheritance involve crating a prototype model that differentiate from original class. For instance when deal with the user and admin instance, we aim to prevent the user instance having access to admin-specific function like delete function.
filter function in javascript allow us to cycle through each element inside the array and filter the specify one of them or more of them
In ES6 you can pass echo individual item as parameter to an arrow function.
e.g. meow=['mewo1','meow2','meow3']
```
meow.Traversed function(m=>{m.??
}) m will be meow1, meow2, mew3
```
## filter()
if it return the true, item will remain in the array
else it returns the false, item will be filtered out and removed from the array
```javascript
class User{
constructor(name,password){
//Hard code
//this.name = "mewohecker"
//this.password="mewohecker"
//dynamic
this.name=name
this.password=password
this.score = 0
}
login(){
console.log(this.name,"just logged in")
return this;
}
logout(){
console.log(this.name, "just logged out")
return this;
}
methodChain(){
this.score++
console.log(this.name,'Now Score is ',this.score)
return this; //return the INstance for using the methodCHain.
}
}
class Admin extends User{ // inheritance all property from original Class
deleteUser(user){
users = users.filter(u=>{
return u.name != user.name
})
}
}
var user1 = new User('meowhecker','mewohecker123')
var user2 = new User('mewomewo','weommoew')
var admin1 = new Admin("meowHacker",'mewohe997')
var users = [user1,user2,admin1]
admin1.deleteUser(user2)
console.log(users)
```

It can be observed that the 'Admin' prototype is class that inherits from 'User' class.

# Constructor (under the hood)
Constructor Function is specialize function be used to create objects.
new -> 'new' keyword is be used to invoke the constructor function, and Access the prototype property to inherit all attributes and methods.
```javascript
// lession 8 constructor (under the hood)
function User(email,name){
this.email=email
this.name=name
this.login = function(){
console.log(`${this.name} has logged in !!!`)
}
}
var user1 = new User('meowhecker','mewohecker123@gggg')
var user2 = new User('mewomewo','weommoew@mewre')
user1.login()
user2.login()
```

# Prototype

the prototype contains methods that accessible to instances created from that object's construct's function
```javascript
function User(email,name){
this.email=email
this.name=name
this.online = false
}
User.prototype.login = function(){
this.online=true
console.log(`${this.name} has logged in !!!`)
}
User.prototype.logout = function(){
this.online=false
console.log(`${this.name} has logged out !!!`)
}
var user1 = new User('meowhecker','mewohecker123@gggg')
var user2 = new User('mewomewo','weommoew@mewre')
user1.login()
user1.logout()
```
user1.__proto__.login() == user1.login()

# Prototype Inheritance
## inherit user attribute
```
function Admin(...args){ // ... pass the parameter as Array
//inherite user attribute
User.apply(this,args) //"this:pass the admin Insntace"
this.role = "super admin"
}
```
## inherit user prototype
```
Admin.prototype = Object.create(User.prototype)
```


```javascript
function User(email,name){
this.email=email
this.name=name
this.online = false
}
User.prototype.login = function(){
this.online=true
console.log(`${this.name} has logged in !!!`)
}
User.prototype.logout = function(){
this.online=false
console.log(`${this.name} has logged out !!!`)
}
function Admin(...args){ // ... pass the parameter as Array
//inherit user attribute
User.apply(this,args) //"this:pass the admin Insntace"
this.role = "super admin"
}
//inherit User prototype
Admin.prototype = Object.create(User.prototype)
var user1 = new User('meowhecker','mewohecker123@gggg')
var user2 = new User('mewomewo','weommoew@mewre')
var admin = new Admin('adminmeow','mewohe@wrew')
user1.login()
user1.logout()
```
## Adding addiction function (prototype)
```
Admin.prototype.deleteUser = function(user){
users = users.filter(u=>{
return u.email != user.email
})
}
```
All Source COde
```javascript
function User(email,name){
this.email=email
this.name=name
this.online = false
}
User.prototype.login = function(){
this.online=true
console.log(`${this.name} has logged in !!!`)
}
User.prototype.logout = function(){
this.online=false
console.log(`${this.name} has logged out !!!`)
}
function Admin(...args){ // ... pass the parameter as Array
//inherite user attribute
User.apply(this,args) //"this:pass the admin Insntace"
this.role = "super admin"
}
Admin.prototype = Object.create(User.prototype)
Admin.prototype.deleteUser = function(user){
users = users.filter(u=>{
return u.email != user.email
})
}
var user1 = new User('meowhecker','mewohecker123@gggg')
var user2 = new User('mewomewo','weommoew@mewre')
var admin = new Admin('adminmeow','mewohe@wrew')
var users = [user1,user2,admin]
user1.login()
user1.logout()
```
