-
Notifications
You must be signed in to change notification settings - Fork 17
/
Beautify JavaScript = Anton Kovalyov;Note=Erxin.txt
236 lines (187 loc) · 5.66 KB
/
Beautify JavaScript = Anton Kovalyov;Note=Erxin.txt
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
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
Beautify JavaScript = Anton Kovalyov;Note=Erxin
# beautifuly mixins
- classical inheritance
- prototypes, prototype is an object that supplies base behavior to a second object
Object.create()
- mixins, is a class that defines a set of functions that would otherwise be defined by a concrete entity
- classic mixins
var Cicle = function(){};
Cicle.prototype = {
area:function(){
return Math.PI * this.radius * this.radius;
},
grow: functio(){
this.radius++;
}
}
here is another simpler mixin defination
var cicleFns = {
area: function(){
return Math.PI * this. radius * this.radius;
}
}
- the extend function, use prototype.js framework omits a hasOwnProperty check, use extend function
function extend(destination, source){
for(var key in source)
{
if(source.hasOwnProperty(key)){
destination[key] = source[key];
}
}
return destination;
}
extend(obj.prototype, mixins);
- functional mixins, use context this to represent the mixin's target object. when create the mixin with modify the this object. It will modify the mixed object properties
var mixin = function(){
this.area = function(){
return math.PI * this.radius * this.radius;
};
};
- adding options
var mixin = function(options){
this.area = function() {
return Math.PI * this.radius * this.radius * options.item;
}
}
mixin.call(target_obj, options);
- adding caching, we can cache the results of the initial definition run
- advice, object.advice redefines a function by adding custom code before, after or around the original implementation. Twitter's Flight framework makes use of functional mixins guards against clobbering by temporarily locking existing properties
advice allows us to augeet third-party library functions
http://flightjs.github.io/
- wrapup
# eval and domain-specific langauges
- what about eval is Evil
- history and interface
eval is only done in the local scope if we can see during compilation
eval(...); //local scope
while(0 || eval)(...) //global scope
var geval = eval;
geval(...); //global scope
- eval may break the javascipt engine optimization
- common uses, dynamically running code from an external source
parse json
template
+ template example
#$in.title#
==============
Items on today's list:
#for item in $in.items#
* #item.name##if item.note# (Note: #item.note#) #end#
#end#
function compile(template) {
var code = "var _out = '';", uniq = 0;
var parts = template.split("#");
for (var i = 0; i < parts.length; ++i) {
var part = parts[i], m;
if (i % 2) { // Odd elements are templating directives
if (m = part.match(/^for (\S+) in (.*)/)) {
var loopVar = m[1], arrayExpr = m[2];
var indexVar = "_i" + (++uniq), arrayVar = "_a" + uniq;
code += "for (var " + indexVar + " = 0, " + arrayVar + " = " +
arrayExpr + ";" + indexVar + "<" + arrayVar + ".length; ++" +
indexVar + ") {" + "var " + loopVar + " = " + arrayVar +
"[" + indexVar + "];";
} else if (m = part.match(/^if (.*)/)) {
code += "if (" + m[1] + ") {";
} else if (part == "end") {
code += "}";
} else {
code += "_out += " + part + ";";
}
} else if (part) { // Even elements are plain text
code += "_out += " + JSON.stringify(part) + ";";
}
}
return new Function("$in", code + "return _out;");
}
- dependencies and scopes, CommonJS(Node.js) or RequireJS modules
function newFunctionWith(env, args, body) {
var code = "";
for (var prop in env)
code += "var " + prop + " = $$env." + prop + ";";
code += "return function(" + args + ") {" + body + "};";
return new Function("$$env", code)(env);
}
console.log(newFunctionWith({x: 10}, "y", "return x + y;")(20));
- debugging generated code
keep the generated code into a seperate file and auto format it, and then try to load it. then when debugging will point to the right code line
- pattern where you should ocnsider reaching for a compiled domain-specific language is
writing chunks of repetitive low density code
performance is important
the chode chunks can conveniently be isolated in functions
you can think of a shorter more elegant notation
# how to draw a bunney
- use || replace the if condtion
if (user_name)
{
set_username();
}
equal to
user_name || set_username()
- replace the swith case..case... to
function getOffset (x, y, w, h, placement) {
var offset
switch (placement) {
case 'bottom':
offset = {
top: y + h,
left: x + w/2
}
break
case 'top':
offset = {
top: y,
left: x + w/2
}
...
equal to
function getOffset (x, y, w, h, placement) {
return placement == 'bottom' ? { top: y + h, left: x + w/2 } :
placement == 'top' ? { top: y, left: x + w/2 } :
placement == 'left' ? { top: y + h/2, left: x } :
{ top: y + h/2, left: x + w }
}
function getOffset (x, y, w, h, placement) {
return {
top : placement == 'bottom' ? y + h :
placement == 'top' ? y : y + h/2,
left : placement == 'right' ? x + w :
placement == 'left' ? x : x + w/2
}
}
- another way to write IIFE
!function (){}()
~function (){}()
+function (){}()
-function (){}()
new function (){}
1,function (){}()
1&&function (){}()
var i=function (){}()
- consider two libraries, Ratchet and Bootstrap
- explode string function for example
String.prototype.explode = function () {
var i
var result = ''
for (i = 0; i < this.length; i++) {
result = result + this[i]
if (i < result.length - 1) {
result = result + ' '
}
}
return result
}
equal to
String.prototype.explode = function (f,a,t) {
for (f = a = '', t = this.length; a++ < t;) {
f += this[a-1]
a < t && (f += ' ')
}
return f //ollow @fat
}
effect of the functions
'alex' to 'a l e x'
String.prototype.explode = function () {
return this.split('').join(' ')
}
# Too much rope, or javascript for teams