-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathFunction-object-NFE.js
More file actions
201 lines (140 loc) · 4.28 KB
/
Function-object-NFE.js
File metadata and controls
201 lines (140 loc) · 4.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
//: Function object, NFE
//* The "name" property
/* Function objects contain some useable properties. For Instance, a function's name is accessible as the "name" property: */
function SayHi() {
console.log("Hi!");
}
console.log(SayHi.name); // SayHi
// the name-assigning logic is smart.
let Hi = function () {
console.log("Hi!");
};
console.log(Hi.name); // Hi
// It also works if the assignment is done via a default values:
function Func(fun = function () {}) {
console.log(fun.name); // fun
}
Func();
/* In the specification, this feature is called a "contextual name". If the function does not provide one, then in an assignment it is figured out from the context. */
let user = {
SayHi() {
// do something
},
SayBye() {
// do something
},
};
console.log(user.SayHi.name); // SayHi
console.log(user.SayBye.name); // SayBye
// There are cases when there's no way to figure out the right name. In that case, the name property is empty
// ? function created inside array
let arr = [function () {}];
console.log(arr[0].name); // "empty string"
// the engine has no way to set up the right name, so there is none
//* The "length" property
/* There is another-built-in property "length" that returns the number of function parameters */
function f1(a) {}
function f2(a, b) {}
function f3(a, b, c) {}
console.log(f1.length); // 1
console.log(f2.length); // 2
console.log(f3.length); // 3
//! Here we can see that rest parameters are not counted.
//? The "length" property is sometime used for introspection in function that operate on other functions.
function ask(question, ...handlers) {
let isYes = confirm(question);
for (let handler of handlers) {
if (handler.length == 0) {
if (isYest) handler();
} else {
handler(isYest);
}
}
}
ask(
"Question?",
() => console.log("You said Yes"),
(result) => console.log(result)
);
//* Custom Properties
function name() {
console.log("Hi");
// let's count how many times we run
name.counter++;
}
name.counter = 0; // intial value
name();
name();
console.log(`Called ${name.counter} times`); // called 2 times
//? A property is not a variable
/* A property assigned to a function like name.counter = 0 does not define a local variable couter inside it. In other words, a proerty counter and a variable let counter are two unrelated things. */
// Function properties can replace closures sometimes.
function makeCounter() {
// instead of:
// let count = 0;
function counter() {
return counter.count++;
}
counter.count = 0;
return counter;
}
let counter = makeCounter();
console.log(counter());
console.log(counter());
console.log(counter());
/* The main difference is that if the value of count lives in an outer variable, then external code is unable to access it. Only nested function may modify it. And if it's bound to a function, then such a thing is possible */
function makeCounter2() {
function counter() {
return counter.count++;
}
counter.count = 0;
return counter;
}
let counter2 = makeCounter2();
counter.count = 10;
console.log(counter()); // => 10
//* Named Function Expression (NFE)
/* Named function expression or NFE is a term for function expressions that a name */
// For instance, let's take an ordinary function expression:
let Hello = function (who) {
console.log(`Hello ${wow}`);
};
// and add a name to it //? => because still create as a part of an assignment expression
let Greeting = function Hello(who) {
console.log(`Hello ${who}`);
};
// -> It allow the function to reference itself iternally.
// -> It is not visible outside of the function
let name = function func(name) {
if (name) {
console.log("Hello ${name}");
} else {
func("Ankit");
}
};
name(); // Hello Ankit
// BUT THIS WON'T WORK
func(); // ERROR, func is not defined (not visiable outside of the function)
// Examples ==> ?
//? Set and decrease for counter
function makeCounterr() {
let count = 0;
function counter() {
return count++;
}
counter.set = (value) => (count = value);
counter.decrease = () => count--;
return counter;
}
//? Sum with an arbitrary amount of brackets
function sum(a) {
let currentSum = 0;
function f(b) {
currentSum += b;
return f;
}
f.toString = function () {
return currentSum;
}
return f;
}