-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path8-function.html
More file actions
385 lines (329 loc) · 9.2 KB
/
8-function.html
File metadata and controls
385 lines (329 loc) · 9.2 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
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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
<script type="text/javascript">
(function(){
function func(){};
func.sname= "wq";
// console.log(func.__proto__,"func");
// console.log(func.prototype,"func"); //可在func.prototype.constructor中找到定义的属性
})();
/**
* 关于留住this的函数,可配合理解bind的写法,
*/
(function(){
var obj = {
hitch: function(scope, method){
return function(){
return method.apply(scope, arguments);
}
},
}
var test = {
say: function(){
// setTimeout(function(){
// console.log(this,"this++")
// },0)
setTimeout(obj.hitch(this,function(){
// console.log(this,"this++")
}),0)
}
}
test.say()
})();
/**
* 8.6: 闭包
*/
(function(){
//闭包存储器
function addPrivateProprety(name,val){
var o ={};
return {
set: function(name){
o[name] = val;
},
get: function(){
return o[name];
},
}
};
var obj = addPrivateProprety("sname","wq");
obj.set("sname");
// console.log(obj.get(),"get");
})();
/**
* 这两个闭包例子
* 注意点: ①闭包中共享变量 ②比保重不希望被共享的变量
*/
(function(){
function constfuncs(v){
return function(){ return v}
};
var funcs = [];
for(var i=0;i<10;i++){
// funcs[i] = constfuncs(i)
var index = i;
funcs[i] = (function(i){
//这里i和index在这打印的值虽然一样但是, 用i是作为闭包的局部变量来使用的
//而index,还是外部的,所以当 funcs[5]()执行时,循环已经都执行完毕了 index= i=9了
//原理同下面的例子
return function(){ return aaa}
})(i);
}
// console.log(funcs[5](),"funcs");
})();
(function(){
//闭包虽然都有,但是闭包中的变量是在 constfuncs() 返回时有变量,所以10个闭包中的变量都一起改变了
function constfuncs(v){
var arr = [];
for(var i=0;i<10;i++){
arr[i] = function (){ return i}
}
return arr;
};
// console.log(constfuncs(),"xx")
})();
/**
* 8.7.6: 构造函数
*/
(function(){
scope = "global";
function constructor(){
var scope = "local";
function fun(){}
return new Function("return this");
};
// console.log(constructor(),"constructor");
var test = new Function();
// console.log(test,"test");
})();
/**
* 8.8,1: 函数式编程
*/
(function(){
//map
var _map = Array.prototype._map
? function(a,f){return a.map(f)}
: function(a, f){
var results = [];
for(var i=0,len=a.length; i<len; i++){
if(i in a){
results[i] = f.call(null, a[i], i, a);
}
}
return results
};
//reduce =>注意 使用reduce是遍历的数组长度必须大于1
var _reduce = Array.prototype._reduce
?function(a,f,initial){
if(arguments.length>2){
return a.reduce(f, initial);
}else{
return a.reduce(f);
}
}
:
function(a,f,initial){
var i=0, len=a.length, accumulator;
if(arguments.length>2){
accumulator = initial;
}else{
if(len == 0){
throw TypeError();
}
while(i<len){
if(i in a){
// break 起到很重要作用,只处理第一个i
//这里的本意就是当没有初始化值,把数组中第一个值作为初始化值使用
accumulator = a[i++];
break;
}else{
i++
}
}
if(i == len){
throw TypeError();
}
}
while(i<len){
if(i in a){
// accumulator:
// accumulator是reduce函数的初始值,会被每一次成功调用iteratee函数的返回值所取代
accumulator = f.call(undefined, accumulator, a[i], i, a);
}
i++;
};
return accumulator;
};
var data = [2,2,2];
var sum = function(x,y){return x+y};
var square = function(x){ return x*x};
var mean = _reduce(data, sum);
// console.log(mean,"mean");
_map(data, function(x){
// console.log(arguments,"xx")
});
//这么写本质上相当于 new一个匿名函数,本身也没什么错,但是 我们要实现的是bind方法功能,
//所以需要继承调用bind的函数属性,级原型
//===========================
// Function.prototype._bind = function(context){
// var args = Array.prototype.slice.call(arguments, 1);
// var self = this;
// return function(){
// this.name="232";
// return self.apply(context, args.concat(Array.prototype.slice.call(arguments)));、
// }
// }
// var obj = {"sname":"wq"};
// function fun(sname){
// this.sname = sname;
// }
// var Bind = fun._bind(obj);
// console.log(Bind("wangqi11"),"Bind");
// var test = new Bind("wangqi")
// console.log(test,"test");
Function.prototype._bind = function(context){
if(typeof this != "function"){ return };
var self = this;
var args = Array.prototype.slice.call(arguments, 1);
function fuBuild(){};
var Func = function(){
//处理是否new的逻辑
var that = this instanceof self ?this: context;
return self.apply(that, args.concat(Array.prototype.slice.call(arguments)))
};
// if(self.prototype){
// fuBuild.prototype = self.prototype
// }
// Func.prototype = new fuBuild();
//这种方式就和es5中的结果也一样,但是为了理解继承建议用上面的(区别: 多了一层fuBuild的空属性)
//且es5的这种 bind()返回的函数没有prototype属性的
Func.prototype = self.prototype;
return Func;
};
var obj = {"sname":"wq"};
function fun(sname){
this.sname = sname
}
fun.prototype = {
say:function(){}
}
var Bind = fun._bind(obj);
// console.log(Bind.prototype,"Bind");
// console.log(new Bind("wangqi"),"Bind")
/**
* 数组的indexOf理解:
*/
// _indexOf = function(array, item, isSoered){
// var i=0, length = (array&&array.length);
// //存在isSoered且为数组情况
// if(typeof isSoered =="number"){
// i = isSoered<0?Math.max(0, length+isSoered):isSoered;
// }
// //匹配NaN
// if(item!=item){
// var findIndex = function(array, predicate, context){
// var length = array!=null &&array.length;
// for(var index=0; index<length; index++){
// if(predicate(array[index])){
// return index;
// }
// }
// return -1;
// };
// var isNaN = function(obj){ return obj !== +obj };
// return findIndex(Array.prototype.slice.call(array,i), isNaN);
// }
// //正常Number
// for(;i<length;i++){
// if(array[i]===item){
// return i;
// }
// };
// return -1;
// };
// var indexT = _indexOf([2,3,4,5],0);
// console.log(indexT,"indexT");
Array.prototype._indexOf = function(item, isSoered){
var i=0, length = (this&&this.length);
//存在isSoered且为数组情况
if(typeof isSoered =="number"){
i = isSoered<0?Math.max(0, length+isSoered):isSoered;
}
//匹配NaN
if(item!=item){
var findIndex = function(array, predicate, context){
var length = array!=null &&array.length;
for(var index=0; index<length; index++){
if(predicate(array[index])){
return index;
}
}
return -1;
}
var isNaN = function(obj){ return obj !== +obj };
return findIndex(Array.prototype.slice.call(this,i), isNaN);
// return findIndex(this, isNaN);
}
//正常Number
for(;i<length;i++){
if(this[i]===item){
return i;
}
};
return -1;
};
var indexT = [2,3,4,5,NaN,6]._indexOf(NaN);
console.log(indexT,"indexT");
})();
(function(){
// map: data.map(function(val, index, list){});
// reduce: data.reduce(function(firstAdd, val, index, list){}, init)
// bind: var val= obj.bind(newObj, arg1, agr2); => 返回一个函数需要再次调用 val();
})();
/**
* 8.8,4: 记忆
* 函数可以将先前操作的结果记录在某个对象里,从而避免无谓的重复运算。这种优化方式被称为记忆
* 记忆是一种编程技巧,本质上是牺牲算法的空间复杂度以换取更优的时间复杂度
*/
(function(){
function memorize(f){
var cache = {};
return function(){
var key = arguments.length + Array.prototype.join.call(arguments, ",");
if(key in cache){
return cache[key];
} else{
return cache[key] = f.apply(this, arguments);
}
};
};
var factorial = memorize(function(n){
return (n<=1)?1:n*factorial(n-1);
});
// console.log(factorial(5), "factorial");
})();
/**
* 理解记忆函数
* https://www.cnblogs.com/zczhangcui/p/6410161.html
* 当函数被调用时,这个函数首先检查结果是否已经存在,如果已经存在,就立刻返回这个结果。
* 这样值操作了 29次 如果不这样处理 需要执行453次
*/
(function(){
var count=0;
var fibonacci=function(){
var memo=[0,1];
var fib=function(n){
count++;
var result=memo[n];
if(typeof result!=='number'){
result=fib(n-1)+fib(n-2);
memo[n]=result;
}
return result;
};
return fib;
}();
for(var i=0;i<=10;i++){
// console.log(fibonacci(i))
}
// console.log(count,"count")
})();
</script>