> For the complete documentation index, see [llms.txt](https://justin-se.gitbook.io/justin-se-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://justin-se.gitbook.io/justin-se-docs/javascript/languagecharacteristic.md).

# Language Characteristic

## **Variable Type**

| type          | **var**   | **let**   | **const** |
| ------------- | --------- | --------- | --------- |
| scope         | function  | block     | block     |
| re-assign     | can       | can       | cannot    |
| initial value | undefined | undefined | -         |

## **Scope**

* block: variable declare at block scope, each indent or bracket "{}" is a block.
* function : variable declare at scope of parent function, can access over block scope

  ```jsx
  function blockScope(){ // start block 1
  	const x = 1;
  	
  	if (true){ // start block 2
  		const y = 2;  
  	}; // end block 2
  	
  	console.log(x,y); // error, can access x, cannot access y
  } // end block 1

  function functionScope(){
  	var x = 1;
  	if (true){
  		var y = 2;  // Same scope as "x"
  	};
  	console.log(x,y); // print : 1, 2
  }
  ```

## **Initial value**

> “declare” and “initialize” is not same things.

when declare a variable without value, “**var”** and “**let"** will initialize value as **“undefined**”.

**“const”** will only declare variable exist without initialize any value,

if we access a const that have no value will cause error.

example :

```jsx
var q;
console.log('q',q); // print "q, undefined"

let w;
console.log('w',w); // print "w, undefined"

const e;
console.log('e',e); // error "Missing initializer in const declaration"
```

## **Object vs Map**

* **Map** are simpler in feature & concept, flexible, and have better performance than Object.
  * map can use anything as key, string, number, even object.
* **Object** have more feature, in large data modifying will NOT perform better than map.
  * Object can only use string as key, use other type as key will convert to string.
  * Object properties come with attribute like writable, enumerable, configurable.
  * Object structure are more like json, easier to convert to json.

## **Prototype**

most of javascript data type have a prototype, as its name “prototype” will contain js built in function, or in OOP concept, its like parent class to let child inherit.

to access a prototype, use “**proto**” keyword.

```jsx
// access string's prototype in browser console
"i am a string".__proto__ // expected: String {'', anchor: ƒ, at: ƒ, big: ƒ, blink: ƒ, …}

// access object's prototype
const x = {};
x.__proto__ // expected: {__defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, __lookupSetter__: ƒ, …}
```

## **Enumerability**

Enumerable is an attribute of **Object** property,

most of iteration feature like **for loop** and **JSON.Stringify()** only access enumarable value.

it can use to :

* hide the internal properties.
* control iteration accessible property to have better performance.
* avoid **Object** to **JSON** conversion error.

an example of using **JSON.stringify()** with enumerable attribute to achive client side only property on same object:

```jsx
const user = {
	name: "jason",
};

// set non enumerable
Object.defineProperty(user, 'rememberPassword', {
  value: true,
  enumerable: false
});

// internal accessing props
console.log(user) // {name: 'jason', rememberPassword: true}

// format object without internal props
console.log(JSON.stringify(user))// {"name":"jason"}
```

due to **JSON.stringify()** do not read non-enumerable value, we can reuse the object by assign non-enumerable property as client side internal props, and filter it out while making payload to send to server.

## Function call() & apply()

* `.call()` Takes individual arguments: `.call(thisArg, arg1, arg2, ...)`
* `.apply()` Takes an array of arguments: `.apply(thisArg, [arg1, arg2, ...])`

Both methods take the first argument as the `this` context within the function scope.\
The `this` keyword refers to the object that is currently calling the function.\
By using `call()` or `apply()`, you can explicitly set the value of `this` inside the function.

```jsx
function test(place){
	console.log(this.name + " live in " + place);
}

test.call({name: "justin"}, "earth"); // justin live in earth
```
