Finished Chapter 8.2.2
parent
95764a8835
commit
0d0e3e01c1
|
@ -1,5 +1,7 @@
|
|||
# Chapter 12. Iterators and Generators
|
||||
|
||||
|
||||
|
||||
## 12.1 How Iterators Work
|
||||
|
||||
## 12.2 Implementing Iterable Objects
|
||||
|
|
|
@ -536,6 +536,8 @@ JSON.stringify([point]) // => '["(1, 2)"]'
|
|||
|
||||
## 6.10 Extended Object Literal Syntax
|
||||
|
||||
|
||||
|
||||
### 6.10.1 Shorthand Properties
|
||||
|
||||
### 6.10.2 Computed Property Names
|
||||
|
@ -547,3 +549,28 @@ JSON.stringify([point]) // => '["(1, 2)"]'
|
|||
### 6.10.5 Shorthand Methods
|
||||
|
||||
### 6.10.6 Property Getters and Setters
|
||||
|
||||
* All obj properties mentioned above are **data properties**. JS also supports **accessor properties** (
|
||||
* A accessor property does not have a value, but has 1 or 2 accessor methods: **getter** or **setter**)
|
||||
|
||||
How accessor property works:
|
||||
* When JS program queries value of this accessor property, JS invoke getter method.
|
||||
* When JS program sets value of the accessor property, JS invokes setter method, and passing value.
|
||||
|
||||
R/W property?:
|
||||
* If a accessor property has both getter & setter, it's a **read/write property**.
|
||||
* If it only has a getter method, it's a **read-only property**.
|
||||
* If it only has a setter method, it's a **write-only property**. (not possible with data properties)
|
||||
* Read it return `undefined`
|
||||
|
||||
Accessor property syntax using an extension to object literal syntax:
|
||||
```js
|
||||
let o = {
|
||||
// An ordinary data property
|
||||
dataProp: value,
|
||||
|
||||
// An accessor property defined as a pair of functions.
|
||||
get accessorProp() { return this.dataProp; },
|
||||
set accessorProp(value) { this.dataProp = value; }
|
||||
};
|
||||
```
|
||||
|
|
|
@ -138,3 +138,115 @@ function hypotenuse(a, b) {
|
|||
```
|
||||
|
||||
Scoping rule of nested function: enclosure function can access param and var of the functions they are nested within (i.e. inner function know outer function's param)
|
||||
|
||||
## 8.2 Invoking Functions
|
||||
|
||||
JS will not execute function body, when function is defined. Rather executed when func is invoked
|
||||
|
||||
5 ways to invoke JS functions:
|
||||
* As functions
|
||||
* As methods
|
||||
* As constructors
|
||||
* Indirectly through `call()`, `apply()`
|
||||
* Implicitly
|
||||
|
||||
### 8.2.1 Function Invocation
|
||||
|
||||
**Invocation Expression**:
|
||||
```js
|
||||
func_name(param1, param2);
|
||||
```
|
||||
* params can be any argument expression. JS will evaluate these expression and then use result as args.
|
||||
* For no `return` function, value of return is `undefined`
|
||||
|
||||
Use **conditional invocation** on invocation expression: invoke the function only if it's not `null` or `undefined`
|
||||
```js
|
||||
f?.(x)
|
||||
```
|
||||
equivalent to
|
||||
```js
|
||||
(f !== null && f !== undefined) ? (fx) : undefined
|
||||
```
|
||||
|
||||
### 8.2.2 Method Invocation
|
||||
|
||||
A **method** = JS function stored in a property of an object.
|
||||
|
||||
* **Defining a function method**, given object `o`, method name `m`, and a function `f`:
|
||||
```js
|
||||
o.m = f;
|
||||
```
|
||||
|
||||
* **Invoking object method**:
|
||||
```js
|
||||
o.m(param1, param2);
|
||||
```
|
||||
|
||||
Method invokation can also use `[]` instead of dot notation:
|
||||
```js
|
||||
o["m"](x,y); // Another way to write o.m(x,y).
|
||||
a[0](z) // Also a method invocation (assuming a[0] is a function).
|
||||
```
|
||||
|
||||
**Invoctaion Context** of invoking by method:
|
||||
* (OOP) In a method-invocation expression, the object become invocation contaxt, the function body can refer to the object by keyword `this` (e.g. shown below)
|
||||
```js
|
||||
let calculator = { // An object literal
|
||||
operand1: 1,
|
||||
operand2: 1,
|
||||
add() { // We're using method shorthand syntax for this function
|
||||
// Note the use of the this keyword to refer to the containing object.
|
||||
this.result = this.operand1 + this.operand2;
|
||||
}
|
||||
};
|
||||
calculator.add(); // A method invocation to compute 1+1.
|
||||
calculator.result // => 2
|
||||
```
|
||||
* `this` is a keyword, not a variable or property name.
|
||||
|
||||
#### Nested function & `this` keyword
|
||||
|
||||
* nested functions do not inherit the this value of the containing function.
|
||||
* If a nested function is invoked as a method, its this value is the object it was invoked on.
|
||||
* If a nested function (that is not an arrow function) is invoked as a function, then its this value will be either the global object (non-strict mode) or undefined (strict mode).
|
||||
* It is a common mistake to assume that a nested function defined within a method and invoked as a function can use this to obtain the invocation context of the method.
|
||||
|
||||
Solution (workaround) 1:
|
||||
```js
|
||||
let o = { // An object o.
|
||||
m: function() { // Method m of the object.
|
||||
let self = this; // Save the "this" value in a variable.
|
||||
this === o // => true: "this" is the object o.
|
||||
f(); // Now call the helper function f().
|
||||
|
||||
function f() { // A nested function f
|
||||
this === o // => false: "this" is global or undefined
|
||||
self === o // => true: self is the outer "this" value.
|
||||
}
|
||||
}
|
||||
};
|
||||
o.m(); // Invoke the method m on the object o.
|
||||
```
|
||||
* Within the method m, we assign the this value to a variable self, and within the nested function f, we can use self instead of this to refer to the containing object.
|
||||
|
||||
Solution (workaround) 2 since ES6 **arrow function**:
|
||||
```js
|
||||
const f = () => {
|
||||
this === o // true, since arrow functions inherit this
|
||||
};
|
||||
```
|
||||
* Functions defined as expressions instead of statements are not hoisted, so in order to make this code work, the function definition for f will need to be moved within the method m so that it appears before it is invoked.
|
||||
|
||||
Solution (workaround) 3 using `.bind(this)`:
|
||||
```js
|
||||
const f = (function() {
|
||||
this === o // true, since we bound this function to the outer this
|
||||
}).bind(this);
|
||||
```
|
||||
|
||||
### 8.2.3 Constructor Invocation
|
||||
|
||||
**Constructor invocation** = function/method invocation proceded by keyword `new`.
|
||||
* Constructor invocation differ from regular function and method invocations in arg handling, invocation context, and return value.
|
||||
* A constructor invocation creates a new, empty object that inherits from the object specified by the prototype property of the constructor.
|
||||
* Constructor functions are intended to initialize objects, and this newly created object is used as the invocation context, so the constructor function can refer to it with the this keyword.
|
Loading…
Reference in New Issue