-
Notifications
You must be signed in to change notification settings - Fork 0
/
js_t
executable file
·3194 lines (2773 loc) · 120 KB
/
js_t
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
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//想起来了,一开始这个内容是跟着youtube上的一个教程学的
*-----Comment Your Javascript Code-----*
0.注释的作用主要是对你写的代码的一个解释说明
1.在执行js代码时注释会被忽略掉(或叫跳过)
2.常见的注释有单行注释和多行注释.
2.1.单行注释:
特点:
0.以双斜线开始,不可跨行;
细分:
行内注释: var number = 1; //即代码后面加注释
打头注释: //整行都是注释,即以"//"打头的行
2.2.多行注释
特点: 0.以/*开始, 以*/结束,中间所有的内容都被看作注释;
1.注释可跨越多行;
例子: /* abc
def
ghi
"/*"与"*/"不一定要对齐,我这里对齐写是因为看着好看
*/
*-----Data Types and Variables-----*
0.javascript提供了7种数据类型:
undefined, null, boolean, string, symbol, number, object
undefined: 声明了但未赋值
var x; //这里只声明了变量x,但未赋值
console.log(x) //此时输出x的值就是undefined
*.值和类型都是undefined?
null:
var x = null;
console.log(x);
boolean:只有两个值, true 和 false
string:由引号引起来的一系列字符
var name = "张三";
var place = "波罗诺";
symbol:
number:
object
var x;
console.log(x)
1.三种声明变量的方式(https://stackoverflow.com/questions/762011/whats-the-difference-between-using-let-and-var):
a.使用var关键字进行声明; //var是variable的缩写
var myName = "Jack";
myName = 9; //对变量重新赋值
b.使用关键字let;
let ourName = "Jack";
ourName = 8; //对变量重新赋值
c.使用关键字const;
const pi = 3.14;
*.再说下var,let,const这三个关键字声明变量的特点:
<a>.值是否可变:var和let声明的变量值是可变的;const声明的值是不可变的也就是我们经常所说的常量(我们所说的常量英文里的描述通常是"不可变的变量",也就是主基调说它是一个"变量",又有一个限定词,"值不能改变的"变量). //注意变量声明时要使用关键字var,let,const,但重新赋值时直接写"变量名 = 新值"即可,并且"新值"的类型与变量定义时的值类型可不同.
<b>.函数中声明变量时的作用域(即都能在哪引用这个变量):var为整个函数,let为其所在的{}:
块 block
{
N条语句
}
有几对hua括号就有几个块(block)
---例子---
function run() {
var foo = "Foo";
let bar = "Bar"; //注意它的作用域
console.log(foo, bar);
{
var moo = "Mooo";
let baz = "Bazz";
console.log(moo, baz);
//console.log(bar)
}
console.log(moo);
console.log(baz);
}
run();
/*console.log(x); //导致脚本终止执行
var y;
console.log(y); //输出值为undefined, 脚本正常执行
null不会自动赋给某个变量
*/
---结束---
window{
name="张三"; //console.log(window.name)
age = 18; //console.log(window.age)
addr = "";
foo = "Foo";
}
<c>.函数外声明变量时,var定义的变量会被被添加为window对象的一个属性(无关键字声明的变量也会成为window对象的一个属性), 而let定义的变量则不会
---例子---
var foo = "Foo";
let bar = "Bar";
console.log(window.foo); //因为window属于浏览器中的一个对象,因此要在浏览器中运行才行
console.log(window.bar);
---结束---
<d>.函数中,使用var定义的变量,变量的引用位于定义之前也不会报错,而是被评估为undefined; let定义的变量则必须是声明位于引用之前,否则运行报错:
---例子---
function run() {
console.log(foo);//foo的引用位于其定义var foo前也不会出错
var foo = "Foo";
console.log(foo);
}
run()
function checkHoisting() {
console.log(foo);
let foo = "Foo";
console.log(foo);
}
checkHoisting()
---结束---
/*
function name(){
}
name()
var x = function(){ //匿名函数 console.log(slfkjadkfj) }
x()
[function(){ //匿名函数 console.log(slfkjadkfj) }]
a[0]()
*/
<e>.正是因为var的作用域要比let广,所以定义变量时var出bug的概率要高于let:
---例子---
var funcs = [];
for(let i = 0; i < 3; i++) { //将var改为let结果就正确了
funcs[i] = function() {
console.log("My value: " + i);
};
}
for (var j = 0; j < 3; j++) {
funcs[j]();
}
/*
funcs数组中存放的是三个匿名函数,如果使用var i的话,这三个匿名函数绑定的就是同一个变量i; 而使用let i则这三个函数每一个绑定的都是不同的i;
因为var在整个过程都有效,而函数在运行的时候才会对里面的变量进行评估,因此funcs中三个函数里的i都是3;
//函数被作为元素追加到数组中时,函数中的变量先不被替换, 只能在函数被调用时才会进行相应变量的替换以及运算等.
{
var i = 0;
funcs[i] = function() {
console.log("My value: " + i);
};
}
{
var i = 1;
funcs[i] = function() {
console.log("My value: " + i);
};
}
{
var i = 2;
funcs[i] = function() {
console.log("My value: " + i);
};
}
var i = 3;
因为let只在其当前的块中起作用,所以可以理解为:
{
let i = 0;
funcs[i] = function() {
console.log("My value: " + i);
};
{
let i = 1;
funcs[i] = function() {
console.log("My value: " + i);
};
{
let i = 2;
funcs[i] = function() {
console.log("My value: " + i);
};
}
let i = 3;
*/
---结束---
<f>.var允许对同一变量进行重复声明, 而let不允许: //这是Firefox的行为, Chrome则是var和let都可以重复声明同一个变量名
---例子---
var bar = "3";
var bar = "4";
console.log(bar);
let foo = "3";
let foo = "4";
console.log(foo);
---结束---
*-----Storing Values with Assignment Operator-----*
0.最好在每个语句后面都以分号结尾, 不加也行,只不过加上的话,可以更直观的看到每条语句的结尾.但要注意的是,如果要加的话,并不是每一行末尾都加,就现在看来流程语句语法本身的语句是不用加的:
---例子---
var a;
var b = 2;
for(){
} //这两行属于for的语法结构,结尾不用加分号,但{}里面的语句要加
if(){
} //这两行同for一样,属于if的语法结构,结尾不用加分号,但{}里面的语句要加
*.如果for和if里面的语句还嵌套for和/或if语句,同理,语法结构的那两行末尾也不用加
---结束---
1.本节的主题所谓的赋值操作符,说白了就是我们常说的等号,=
2.而"赋值操作符"的作用说白了就是给变量赋值,上面已经说过变量赋值了,这里再强调一下常见的用法:
---例子---
var a;
var b;
b = 3;
var c = 4;
c = "张三";
console.log(a) //只声明未赋值,因此a的输出为undefined
console.log(b) //先声明,后赋值,所以b是有值的,为3;
console.log(c) //声明的同时对变量赋值,后面又对变量重新赋值,输出的是对变量最后一次赋的值; 需要注意的是,变量多次赋值时,值的类型可以不同.
---结束---
3.null与undefined的区别(http://net-informations.com/js/iq/nuvsun.htm):
a.首先null是一个值,它的类型为object,只不过这个object类型的值里面啥都没有,是空的;
---例子---
var a;
var b = null;
console.log(a) //值为undefined
console.log(b) //值为null
console.log(typeof a) //undefined的类型为undefined
console.log(typeof b) //null的类型为object
---结束---
b. 当变量只声明,未赋值时,变量的值为undefined类型值undefined;而null通常是起占坑的作用,即后面可能会给变量x赋一个值, 但现在还不知道赋啥,可以先写一句var x = null; 后面可以通过if语句来判断x的值是否为null来知道变量x是否已经被重新赋值了(即如果x的值不是null了,则肯定是被重新赋值了).
---例子---
var a;
console.log(a);
console.log(typeof a);
var b = null; //b是object类型
b = 6
if(b==null){
console.log("b还没有被重新赋值")
b = 4
console.log("b的新值为: " + b)
}
//null是object, 特点对象里啥都没有,是空的, 容qi, 空的.
var arr = [1,2,3,4] //声明一个数组,并赋初始值为1,2,3,4
console.log(typeof arr) //object
console.log(arr) //[1,2,3,4]
arr = null //用来清空对象类型的变量,可以把object类型的变量想象为一个容器
console.log(arr) //null
console.log(typeof arr) //object
---结束---
c.未赋值的变量其值为undefined, 如果函数中的形参未被赋值,则其值为undefined, 无return语句的函数的函数返回值为undefined(即每个函数都会有返回值,当显式的指定了return返回语句时,return后面的值就是函数的返回值; 当未指定return返回语句时,默认为reutrn undefined)
var name = "高天";
function hi(any){
console.log("hi, " + any)
}
hi()
hi(name)
function name(){ //函数的返回值
return 1234
} //函数返回值为1234
function name(){} //函数的返回值为undefined
---例子---
var a;
console.log(a)
function test(x){ //函数参数形参和实参, 形参:定义函数时括号里的变量名; 实参是在调用函数时传给形参的值或变量
console.log(x)
}
test()
test(3)
function hello(){
var b = 4;
return b;
console.log("我是不会输出的")
}
var result = hello() //var result = 4
console.log(result)
//console.log(hello())
function hello1(x){
var b = 4;
return arguments //
}
result = hello1("张三","李四") //函数参数都会被放到arguments中,即使定义函数时未指定形参
console.log(result)
//console.log(hello1())
---结束---
d.使用未声明的变量会报错, 使用声明但未赋值的变量返回值为undefined
---例子---
console.log(x) //因为x未被定义,脚本到这就终止了
console.log("这句是不会被执行的")
var y;
console.log(y)
---结束---
e.比较两个变量是否相同有两个操作符,两个等号,==, 和三个等号,===.在javascirpt中null和undefined,从表面意思上理解都有"无"的意思,所以 null==undefined的结果是true. 而三个等号表示严格比较,此时null是object类型而undefined是undefined类型,所以null===undefined的结果是false.
---例子---
console.log(null===null); //true
console.log(undefined===undefined); //这两个undefined都表示的值,因为类型是不能比较的 true
console.log(null===undefined) //false
console.log(null==undefined) //true, 相等的原因https://262.ecma-international.org/5.1/#sec-11.9.3
---结束---
f.当进行算数运算时, null值被评估为0, 而undefined值被评估为NaN
---例子---
var x;
console.log(x + 100); //结果为NaN
var y = null;
console.log(y + 100); //结果为100
---结束---
g.值null是json中的有效值, 而值undeifned不是
*-----Initializing Variables with Assignment Operator-----*
0.说白了就是使用等号给变量赋值
---例子---
var b = 9; //var用来声明变量b,使用=9对b进行初始化
//通常读作声明一个变量b并赋初始值为9
---结束---
*-----Uninitialized Variables-----*
0.未初始化的变量简单来说就是"只声明未赋值"的变量,其默认初始值为undfined
---例子---
var a;
var b;
var c;
console.log(a)
console.log(b)
console.log(c)
---结束---
1.变量参与的运算,a.当操作数都是数值类型时,会自动进行算数运算;b.当操作符都是字符串时,会将字符串进行连接.
---例子---
var a = 5;
var b = "I am "
a = a + 1
b = b + "Jack"
console.log(a)
console.log(b)
---结束---
*-----Case Sensitivity in Variables-----*
0.在javascript中, 变量名和函数名是大小写敏感的,所谓大小写敏感指的是name与Name是不同的变量或函数名.
---例子---
let name = "Lucy";
let Name = "Lily";
console.log(name)
console.log(Name)
function name(){
console.log("Lowercase")
}
function Name(){
console.log("Uppercase")
}
name()
Name()
---结束---
1.在给变量命名时,如果你想的变量名由多于1个单词组成,则可以用驼峰命名法,即第一个单词的首字母小写,其它单词的首字母大写: myNameIsGaoTian
*-----Adding Numbers-----*
0.js中数字加法运算
---例子---
var sum = 10 + 10; //声明变量的同时,使用加法表达式的值进行赋值
console.log(sum)
var sum = 10; //运算和声明分着写形式
sum = sum + 10;
console.log(sum)
var sum = 10; //sum=sum+10还可写作sum+=10
sum += 10;
console.log(sum)
var sum; //变量声明\赋值\运算均分开写的形式
sum = 10;
sum +=10;
console.log(sum)
---结束---
*-----Subtracting Numbers-----*
0.js中的数字减法运算
---例子---
将上一节例子中的加号变成减号即是该节的例子
var sum = 10 - 10; //声明变量的同时,使用减法表达式的值进行赋值
console.log(sum)
var sum = 10; //运算和声明分着写形式
sum = sum - 10;
console.log(sum)
var sum = 10; //sum=sum-10还可写作sum-=10
sum -= 10;
console.log(sum)
var sum; //变量声明\赋值\运算均分开写的形式
sum = 10;
sum -=10;
console.log(sum)
---结束---
*-----Multiplying Numbers-----*
0.js中的数字乘法运算
---例子---
var sum = 10 * 10; //声明变量的同时,使用减法表达式的值进行赋值
console.log(sum)
var sum = 10; //运算和声明分着写形式
sum = sum * 10;
console.log(sum)
var sum = 10; //sum=sum*10还可写作sum*=10
sum *= 10;
console.log(sum)
var sum; //变量声明\赋值\运算均分开写的形式
sum = 10;
sum *=10;
console.log(sum)
---结束---
*-----Dividing Numbers-----*
0.js中的数字除法运算
---例子---
var sum = 10 / 10; //声明变量的同时,使用减法表达式的值进行赋值
console.log(sum)
var sum = 10; //运算和声明分着写形式
sum = sum / 10;
console.log(sum)
var sum = 10; //sum=sum/10还可写作sum/=10
sum /= 10;
console.log(sum)
var sum; //变量声明\赋值\运算均分开写的形式
sum = 10;
sum /=10;
console.log(sum)
---结束---
*-----Incrementing Numbers-----*
0.变量名后跟两个加号,表示变量值加1
---例子---
var counter = 1;
counter = counter + 1; //或counter += 1;
console.log(counter)
var counter = 1;
counter++;
console.log(counter)
---结束---
*-----decrementing Numbers-----*
0.变量名后跟两个减号,表示变量值减1
---例子---
var counter = 1;
counter = counter - 1; //或counter -= 1;
console.log(counter)
var counter = 1;
counter--;
console.log(counter)
---结束---
*-----Decimal Numbers-----*
0.定义一个变量用来存放小数 //这里翻译为十进制数比小数更精确一些
---例子---
var decimalNumber = 8.9;
console.log(typeof decimalNumber)
---结束---
*-----Multiply Decimals-----*
0.小数之间的乘法
---例子---
var result = 2.0 * 2.5;
console.log(result)
---结束---
*-----Divide Decimals-----*
0.小数之间的除法
---例子---
var result = 8.0/2.0;
console.log(result)
---结束---
*-----Finding a Remainder-----*
0.取余运算,或叫取模
---例子---
var result = 8%3;
console.log(result)
---结束---
*-----Compound Assignment with Augmented Addition/Subtraction/Multiplication/Division-----*
---例子---
var x +=3; //注意不能在声明变量时使用复合赋值符号
console.log(x)
var a = 3;
a += 4; //加
console.log(a)
var b = 4;
b -= 1; //减
console.log(b);
var c = 2;
c *= 3; //乘
console.log(c)
var d = 6;
d /= 3; //除
console.log(d)
---结束---
*-----Declare String Variables-----*
0.单引号,双引号,反引号括起来的字符都是字符串类型
---例子---
var a = "hello,"
var b = 'My name is '
var c = `Jack!`
console.log(typeof a)
console.log(typeof c)
console.log(a+b+c) //字符串的连接方式,加号
console.log(a + "slkdfj" + b + "dlfkj" + c)
---结束---
*-----Escaping Literal Quotes in Strings-----*
0.我们都知道 单引号, 双引号, 反引号 引起来的字符序列都可以是字符串, 那么如果字符序列中也含有引号要怎么处理呢?
两种方法:
a.序列中的引号类型和最外层的引号类型一样时,可以将序列中的引号前缀一个反斜杠对其进行转义,让解释器认为序列中的引号不是作为字符串开头或结尾的标志,就是一个普通的字符.
b.使用与字符序列中类型不同的引号
c.如果字符序列中三种引号都有,最外层使用序列中类型最少的那类引号,并将序列中该类引号使用反斜杠进行转义
---例子---
var str = "My name is \"Lucy\""
console.log("My name is \"Lucy\"") // 'My name is \'Lucy\'' `My name is \`Lucy\``
console.log("123\n456") //转义字符"\"来说,它后面是跟单个字符,作用分为两种,一种是将有特殊意义的字符作为普通字通字符对待, \\,\',\";另一种正好相反,将某些普通字符进行转义可以使其有特殊意义,\t,\n,\r
console.log(str)
var str = 'My name is "Lucy"'
var str1 = `My name is "Lucy"`
console.log(str)
console.log(str1)
var str = 'My friends are "lucy", \'Lily\' and `Jack`'
console.log(str)
---结束---
for(let i=0;i<2;i++){ // 0, 1
for(let j=0;j<2;j++){ //0, 1
console.log(i,j)
}
console.log(i)
for(let k=0;k<2;k++){ //0,1
console.log(i,k)
}
console.log(i)
}
同一关键字可以多次声明同一变量:
var i = 1
var i = 2
var i = 3
let i = 1 //报错,因为使用不同的关键字let又声明了一次i
不同关键字:
var i = 1
let i = 1 //报错,理由同上
let i = 1
var i = 1 //报错,理由同上
var a = 6;
*-----闭包(function closure)-----*
0.先引出几个概念(不是什么新概念):
函数内嵌
全局变量
外部变量 //variables in surrounding functions(或叫outer functions)
局部变量 //functions itself variables declared
1.从闭包的英文名中也可以看出, 闭包其实是函数的相关操作.简单来说闭包就是内嵌函数对外部变量的引用(这里的外部变量指的是内嵌函数所在函数中声明的变量).
2.闭包主要有两个特点:
a.从外部特征来看,首先就是要有函数的嵌套(即在函数里面又声明了函数);可以存在多层嵌套.
b.调用外层函数时,返回值为内层函数,也就是说,当你调用外层函数时,返回的并不是一个普通值,而是另一个函数(既然是函数就说明可以被调用).
c.最实用的一点是,外层函数中声明的变量状态会保留下来, 也就是说多次调用返回的内层函数时,下一次内层函数引用的外层函数中的变量值并非初始值,而是上一次内层函数调用时产生的结果.
---
1.变量
---例子---
var glo = 0; //abbreviation global
function name(x){
var outer = 1;
function age(y){
var inner = 2;
var sum = inner + y + outer + x + glo
return sum
}
console.log(age(4))
}
name(5)
---结束---
如果函数有多层内嵌,则最里面的函数,可以访问到所有外层函数中的变量,包含形参变量
---例子---
function init(){ //initialization initial
var name = 'Jack';
function displayName(){
console.log(name);
return 1234
}
console.log(displayName());
}
init();
---结束---
闭包(函数)初现
---例子---
function init(){
var counter = 0;
var sum = counter + 1
return sum
}
console.log(init())
console.log(init())
console.log(init())
---
闭包函数特点:
*0.闭包函数定义: 它是"引用了父函数本地变量"的作为"父级函数返回值"的"内嵌函数"
*0.闭包函数的目的是对返回函数进行多次调用,而每一次调用时,所引用的父级函数中的变量都会受上一次调用的影响
//会受影响的情况即内嵌函数中会改变其引用的父函数中变量的值
function init(){ //内嵌函数可以引用父函数中声明的本地变量
var counter = 0;
function addOne(){
counter += 1 //改变了父函数中形参变量x的值
return counter
}
return addOne
// return addOne()
}
var b = init()
console.log(b())
console.log(b())
console.log(b())
b()
b()
b()
//不会影响的情况 //不是不会影响,size虽是形参, 但形参说白了也是父级函数的本地变量, 之所以下面三次调用size值都一样,是因为内层函数本来也没有改变size变量值的语句, 仅仅是引用.
function makeSizer(size){
return function(){
document.body.style.fontSize = size + 'px';
};
}
var size12 = makeSizer(40);
size12()
size12()
size12()
---
function makeAdder(x){ //内嵌函数可以引用父函数中声明的本地形参变量
return function(y){
return x + y; //没有改变父函数中形参变量x的值
}
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);
console.log(add5(2))
console.log(add10(2))
console.log(add5(2))
console.log(add10(2))
console.log(add5(2))
console.log(add10(2))
---结束---
*****youtube中关于垃圾回收与闭包那块的理解*****
首先一个函数执行完成后, 内存中相应分配给其执行的内存会被回收, 如g函数执行后被回收了, 但f函数没有被回收, 因为f函数中引用了"Lambda g", 而var myG=f(1)也引用了"Lamda g", 如果g函数执行完内存被回收后, f函数执行时分配的内存也被回收,则由于此时myG变量还存在, 如果你后面再调用myG()时(实际调的是Lamda g),g函数引用其外层函数f()中的变量就找不到了,因为f()执行时分配的内存已经被回收了, 所以分配给f函数执行时的内存没有被回收. 我感觉通过这种理解方式也可以, 视频中给的是只要主函数存在一条能够到达对象的路径, 则分配给该对象与与分配给和它有关联的内存都不会被回收
----
0.函数?
ii::基本上一个函数实现一个功能. 什么叫功能呢?说白了就是做某件事情的过程,只不过这个过程的每一步都用代码表示出来
---例子---
实现的功能叫"回学校"
逻辑:
1.先出家门;
2.坐车去滦平;
3.从滦平坐车去北京;
4.从北京坐车到保定;
5.下车打车去学校;
6.到宿舍;
function backSchool(){
1.
2.
3.
4.
5.
6.
}
backSclool() //函数的特点,可复用.
---结束---
1.如何定义一个有名函数?
---例子---
//无参有名函数
function fun1(){ //这里()中放的是形参列表,形参数可以是0个或多个
}
//含有1个形参的有名函数
function fun1(num1){
}
//含有3个形参的有名函数
function fun1(num1,num2,num3){
}
---结束---
2.如果定义一个匿名函数?
---例子---
//无参匿名函数
function(){
}
//有参匿名函数
function(num1,num2){
}
*.上面两种形式,只是为了练习其语法格式, 实际在代码中不能这样写,这样写会报错,说没有函数名; 要想不报错, 要用圆括号给包围起来.
---结束---
3.如果调用有名函数?
---例子---
//定义一个无参有名函数并调用
function fun1(){}
fun1()
//定义一个含有2个形参的函数fun1,并调用
function fun1(num1,num2){
引用num1和num2 //增加函数的灵活性,
}
fun1(1,2)
//给函数定义形参的目的是能让函数语句块中的语句能引用形参. 从而在调用函数的时候通过给函数传递不同的参数让函数产生不同的结果,这样可以增加函数的灵活性
//未定义函数参数
function fun1(){
var sum = 1 + 2
console.log(sum)
}
//定义函数参数
function fun1(num1,num2){
var sum = num1 + num2;
console.log(sum)
}
var x = fun1(1,2)
console.log(x)
---结束---
4.如何调用匿名函数(常见2种方式)?
4.1.定义的同时就调用了:
---例子---
//无参匿名函数,定义的同时执行,此时需要注意的是当函数单独存在时,必须要使用圆括号包围起来,否则报错: "函数没有函数名"
(function(){
console.log("666")
})()
//有参匿名函数,定义的同时执行
//用函数的返回值替代掉函数的调用
var x = (function(num1,num2){
var sum = num1 + num2
return sum
})(1,2)
console.log(x)
console.log((function(num1,num2){
var sum = num1 + num2
return sum
})(1,2))
---结束---
4.2.将函数赋值给某个变量,之后使用该变量作为函数名进行调用:
---例子---
//将无参匿名函数赋给变量fun
var fun = function(){
console.log("我是无参匿名函数的输出")
}
fun()
---结束---
*.需要注意的是,a."单独定义"匿名函数的同时进行调用时,匿名函数要使用小括号包围;b.如果是将匿名函数作为变量值,以及c.将匿名函数的返回值作为变量值时,则b,c用不用小括号将其包围都可以
---例子---
//a.
(function(){
console.log("balabala")
})
(function(){
console.log("balabala")
})() //匿名函数一定要用小括号包围起来,否则会报错
//b.
var fun = [(]function(){ //声明的是变量fun,fun的值为一个匿名函数
console.log("aaa")
}[)]
fun()
//c.
var x = function(){ //声明的是变量x, x的值是匿名函数的返回值
console.log("balabala")
}()
var x = (function(){ //声明的是变量x, x的值是匿名函数的返回值
console.log("balabala")
reuturn func(){}
})()
-----
function name(){
console.log("12345")
}
name()
var alias = name
alias()
function name(){
console.log("12345")
}
var value = name()
value() //这样写是错的,因为上面name函数的返回值是undefined类型,而不是函数类型
-----
var name = function(){
console.log("12345")
}
name()
var alias = name
alias()
var name = function(){
console.log(name)
}
var value = name()
value() //这样写是错的,因为上面name函数的返回值类型undefined,而不是函数
*.只有函数的调用形式才是 "函数名+ ()"
var e = 10;
function sum(a){
return function(b){
return function(c){
return function(d){
return a + b + c + d + e
}
}
}
}
result = sum(1)(2)(3)(4) //返回值1 + 2 + 3 + 4
console.log(result)
function name(){
return function(a){
return function(b){
return a+b
}
}
}
//console.log(name()(1)(2))
x = name()
y = x(1)
console.log(y(2))
function name(){
return 8
}
console.log(name())
-----
小标题:当只希望能通过,A,B,C函数可以访问D函数,其它函数不能访问D函数的情况下
---例子---
var counter = (function(){
var privateCounter = 0;
function D(val){
privateCounter += val
}
return {
A: function(){
D(1);
},
B: function(){
D(-1);
},
C: function(){
return privateCounter;
}
};
})()
console.log(counter.C()) //0
counter.A() //将privatecounter的值变为1
console.log(counter.C()) //1
counter.B() //将privatecounter的值变为0
console.log(counter.C()) //0
---
var counter = function(){
var privateCounter = 0;
function D(val){
privateCounter += val
}
return {
A: function(){
D(1);
},
B: function(){
D(-1);
},
C: function(){
return privateCounter;
}
};
}
//每次调用counter()函数时,都会产生一个新对象, 每个新对象中privateCounter变量的初始值都为0
var v1 = counter()
var v2 = counter()
var v3 = counter()
v1.A() //privateCounter =1
v2.A() //privateCounter =1
v1.A() //privateCounter =2
v3.A() //privateCounter =1
---结束---
----好例分析----
<html>
<body>
<p id="help">Helpful notes will appear here</p>
<p>E-mail: <input type="text" id="email" name="email"></p>
<p>Name: <input type="text" id="name" name="name"></p>
<p>Age: <input type="text" id="age" name="name"></p>
</body>
<script>
function showHelp(help){
document.getElementById('help').textContent = help;
}
function setupHelp(){
var helpText = [
{'id':'email', 'help':'Your e-mail address'},
{'id':'name', 'help':'Your full name'},
{'id':'age', 'help':'Your age (you must be over 16)'}
]
for(var i=0; i < helpText.length; i++){
var item = helpText[i];
document.getElementById(item.id).onfocus = function(){
showHelp(item.help);
}
}
}
setupHelp();
</script>
</html>
---
{
var i = 0
var item = helpText[0]
'email'.onfocus=function(){ showHelp(item.help)}
}
{
var i = 1
var item = helpText[1]
'name'.onfocus=function(){ showHelp(item.help)}
}
{
var i = 2
var item = helpText[2]
'age'.onfocus=function(){ showHelp(item.help)}
}
-----
{
var i = 0
let item = helpText[0]
'email'.onfocus=function(){ showHelp(item.help)}
}
{
var i = 1
let item = helpText[1]
'name'.onfocus=function(){ showHelp(item.help)}
}
{
var i = 2
let item = helpText[2]
'age'.onfocus=function(){ showHelp(item.help)}
}
----------------
闭包总结:
1.闭包函数提供了一种内层函数语句可以引用(或说访问)外层函数中定义的变量的能力.
*.闭包不一定要返回内嵌函数,只要a.有内嵌函数,b.内嵌函数访问了外层函数中的变量即可(这句话不对, 即外层函数的返回值应该一定是内层函数),只不过返回内嵌函数会更有用一些(最常见的情况就是本次调用会影响到下次调用时外层变量的值).
---例子---
function init() { //该init不是闭包, 因为其返回值非内层函数
var name = 'Mozilla';
function displayName() {
alert(name);
}
displayName();
}
init(); //调用函数其实执行的是函数定义里的代码块