技术文章 | jishuwenzhang

北京html5培训之JavaScript学习笔记(D4)

北京html5培训之课堂笔记

(本课程共8天)
 

一、北京html5培训函数

函数就是功能。我们可以自己封装一些语句在函数内部,函数就具有了某一种特定的功能。
function:功能。
函数内部可以封装一段语句,这些语句是一个整体,调用的时候,这些语句要全部一起执行。
函数声明:function 函数名称 (){
 
}
大括号中书写我们想要执行的语句。(结构体)
函数的声明只是告诉我们函数里面有哪些语句。并不会执行。
调用函数 函数名();
优点1:可以把一些重复性的语句封装在函数内部,多次调用。简化代码书写。
 

1 // 函数的声明
2 function fun(){
3 // 要执行语句
4 alert(1);
5 alert(2);
6 alert(3);
7 }

9 // 函数的调用
10 fun();

1.1 函数的声明和调用

函数的声明:
函数的声明使用关键字function(功能)后面紧跟空格,然后书写函数名,函数名后面紧跟小括号(参数),参数可以省略。
函数名的命名规则和变量是一样。

1 function sum(a,b){
2 console.log(a + b);
3 }
函数只有先声明,才能够调用。
函数的声明只是告诉我们函数内有封装了哪些语句,并不会执行。
函数的执行必须调用。
函数的调用:函数名()表示函数的调用。

1 // 函数的调用
2 sum(1,"2");
函数的执行和声明位置没有关系只和调用位置有关系。
1 // 函数的声明
2 function fun(){
3 console.log(10);
4 }
5 console.log(1);
6 console.log(2);
7 fun();
8 console.log(3);
9 console.log(4);
10 fun();
 
 

1.2 参数

函数可以帮我们封装一些代码,代码可以重复调用,函数留了一个接口,就是我们的参数,可以通过参数的变化让我们的函数发生不同作用。
参数都是变量:命名规则与变量一样。
调用过程中给函数传递参数的过程就是一个给变量赋值的过程。
 

1 function sum(a,b){
2 console.log(a + b);
3 }
4 sum(3,4)  //函数有求和的作用
5 sum(3,"4") //作用是拼接作用
js是一个动态类型数据语言,变量的数据类型根据里面存放的内容而变化。
实参的数据类型会影响形参的数据类型。
实参可以传任意类型的值。
 
实际参数:函数调用时传递的参数,叫做实际参数。(实参)
形式参数:函数定义时使用的参数叫做形式参数。(形参)
传参:函数执行时,将实际参数赋值给形式参数,这个过程叫做传参。(赋值过程)
 
参数的个数:
实参个数多于形参个数,将多于实参直接舍弃。

1 // 函数的声明
2 function sum(a,b){
3 console.log(a + b);
4 }
5 // 实参个数多于形参
6 sum(2,3,4,5,6)
 
实参个数少于形参,会优先将赋值给前面参数。

1 // 实参个数小于形参。
2 sum(2);
实参2优先赋值给a = 2, b没有赋值,b = undefined    执行过程2 + undefined = NaN。
 
我们函数都有一个自带属性,arguments,是由函数的实际参数组成的数组。

1 sum(3,5,"你好");
 
函数的优点2:函数有参数,相当于给我们提供一个API接口,我们可以通过接口去调用函数,执行不同的操作,后面封装函数的时候,只需要了解API的用途就够了,就是传参之后有什么结果,不用去了解函数里面的构造。不论是自己的函数还是用的别人封装好的函数,都只需要知道怎么用就够了。

1.3 return语句

函数的变量可以通过参数接收,还可以使用return。
return接收变量,会返回一个值。但是不会输出结果。想看输出结果,在函数调用用输出语句输出

1 // 函数的声明
2 function fun(a,b){
3 return a + b;
4 }
5 // 函数的调用
6 alert(fun(2,4));
返回值将我们的函数矮化成了一个表达式。利用这个特性,我们可以将函数作为一个实际参数,传递给另外一个函数。
 

1 // 函数的声明
2 function fun(a,b){
3 return a + b;
4 }
5 // 函数的调用
6 // alert(fun(2,4));
7 console.log(fun(1,fun(2,3)));
8 console.log(fun(fun(4,3),6));
9 // a = 4 + 3
10 // b = 6
11 // fun(7,6)
12 // console.log(13)
函数的优点3:我们可以将一个函数作为返回值,传递给另外一个函数。有利于我们的模块化编程。
return的特点:函数遇见return,会直接返回。会立即停止return后面语句的执行。
 

1 // 函数的声明
2 function fun(){
3 console.log(1);
4 console.log(2);
5 console.log(3);
6 return;
7 console.log(4);
8 console.log(5);
9 }
10 // 函数的调用
11 fun()
 

1.4 模块化编程

人类从古至今,习惯将事情分工,将一些内容做成一些公共模块,模块可以重复反复使用。
模块化编程:将一些基础的公共的部分单独封装到一个函数内,可以多次被调用。
案例:输出10000以内的质数,模块化编程。
逆向思维的过程:输出10000以内的质数  →  判断是不是质数   →  找约数个数
注意:模块化编程,可以让我们的程序更加优化,各个小模块要尽量功能单一,提高重复使用率。
 

1 // 输出10000以内的质数 → 判断一个是不是质数 → 求这个数的约数个数

3 // 求一个数的约数个数

5 function yueshu(a){
6 // 8
7 var sum = 0;
8 for(var i = 1 ; i <= a ; i ++){
9 if(a % i == 0){
10 sum ++;
11 }
12 }
13 return sum;
14 }
15 
16 // console.log(yueshu(6));
17 
18 
19 // 判断一个数是不是质数
20 function isZhishu(b){
21 if(yueshu(b) == 2){
22 return true;
23 }else{
24 return false;
25 }
26 }
27 
28 // console.log(isZhishu(13));
29 
30 for(var i = 2 ; i <= 10000 ; i ++){
31 if(isZhishu(i)){
32 console.log(i);
33 }
34 }
找1000以内的完美数:(一个数的约数除了它本身外其他约数和还等于这个数)。
 

1 // 找1000以内的完美数:(一个数的约数除了它本身外其他约数和还等于这个数)。
2 // 6 = 1 + 2 + 3
3 // 输出1000以内的完美数 → 判断一个数是不是完美数 → 求约数和


6 // 约数和
7 function yueshuhe(a){
8 var sum = 0;
9 for(var i = 1 ; i < a ; i ++){
10 if(a % i == 0){
11 sum += i;
12 }
13 }
14 return sum;
15 }
16 // console.log(yueshuhe(6));
17 
18 // 判断一个数是不是完美数
19 function isWanmei(b){
20 if(yueshuhe(b) == b){
21 return true;
22 }else{
23 return false;
24 }
25 }
26 
27 // console.log(isWanmei(5));
28 function shuchu(c){
29 for(var i = 1 ; i <= c ; i ++){
30 if(isWanmei(i)){
31 console.log(i);
32 }
33 }
34 }
35 
36 shuchu(1000)
 

1.5 函数表达式

函数的声明(定义)我们使用关键字function。
函数定义还可以使用函数表达式。
函数表达式也是函数定义的一种形式,是将一个匿名函数赋值给一个变量。
匿名函数就是没有名字的一个函数(拉姆达函数)。
函数表达式调用,变量名加小括号()。
 

1 // 函数的声明
2 var fun = function(){
3 console.log(1);
4 };

6 // 函数的调用
7 fun();
 
function关键字定义函数时,不写要在函数最后书写分号;而函数表达式要求函数最后必须书写分号。

1 var fun = function(){
2 console.log(1);
3 };
4 function fun1(){
5 console.log(2);
6 }
 

1.6 函数的数据类型

简单数据类型:number,string,boolean,undefined, null
引用数据类型:object,function,array,Regexp

1 var fun = function(){
2 console.log(1);
3 };

5 function fun1(){
6 console.log(2);
7 }

9 console.log(typeof fun);
10 console.log(typeof fun1);
 
简单数据类型:变量可以进行赋值,变量可以接受任何数据类型。不同变量之间进行赋值运算时,只是将变量的值进行复制然后在赋值给另一个变量。当一个变量的值改变时,其他的不会受影响。
 

1 // 简单数据类型赋值
2 var a = 10;
3 var b;
4 b = a;
5 a = 20;
6 console.log(a);
7 console.log(b);
引用数据类型:在进行赋值时,而是将变量的指针(地址),赋值给另一个变量。当一个变量改变时,另一个变量也会受影响。
 

1 var fun1;
2 function fun(){
3 console.log(1);
4 }
5 fun1 = fun;
6 fun1.xixi = "嘻嘻";
7 fun.haha = "哈哈";

9 console.log(fun.xixi);
10 console.log(fun1.haha);
 
简单数据类型复制的是值,引用数据类型复制的地址。

1.7 函数声明的提升

变量声明的提升:变量可以先使用,后声明。在计算机预解析时,会将所有变量声明提升到语句最前面。使用不会报错,但是只提升变量声明,不提升变量的赋值。输出undefined。
函数声明的提升。函数也可以先使用,后声明。因为在计算机预解析时,同样也是将函数的声明提升到语句最前面,又因为函数存储的是地址,也就是将函数的定义全部提升到了最前面。使用不会报错。
函数表达式不能提升函数声明头:因为函数表达会是变量声明的,相当于只提升的是变量名,后面用小括号调用时会报错。不再是函数。
 

1 fun();
2 fun1();
3 // 关键字function声明函数
4 function fun(){
5 console.log(1);
6 }
7 // 函数表达式
8 fun1 = function(){
9 console.log(2);
10 };
 
要求大家:实际工作中一般使用function关键字定义函数,而不是使用函数表达式。以防出错。
我们习惯先调用函数,将函数的声明放在最后。使代码清晰可读。
 
如果代码中有变量名,函数名相同时,函数名会优先提升。也就是说将这个相同的标识符给了函数。
 

1 console.log(fun);

3 function fun(){
4 console.log(1);
5 }

7 var fun = 3;
 
1 console.log(fun);
2 function fun(){
3 console.log(1);
4 }
5 var fun = function(){
6 console.log(2);
7 }
 
 

1.8 递归函数

递归函数:在函数内部调用自身函数。
一般递归函数用于数学问题。

1 function fun(a,b){
2 return a + fun(a,b);
3 }
4 fun(3,4)
 
斐波那契数列:1 ,1 ,2 ,3 ,5, 8,13,21……

1 function feibo(a){
2 if(a == 1 || a == 2){
3 return 1;
4 }else{
5 return feibo(a - 1) + feibo(a - 2);
6 }
7 }

9 console.log(feibo(1));
10 console.log(feibo(2));
11 console.log(feibo(3));
12 console.log(feibo(4));
13 // feibo(4) = feibo(2)+feibo(3)
14 //          = 1 + feibo(2)+feibo(1)
15 //          = 1 + 1 + 1
16 //          = 3
17 console.log(feibo(10));
18 // console.log(feibo(100));
 

1.9 变量的作用域

在函数中声明的变量,只能在函数内部使用,在函数外部任何地方都不能访问的到这个变量。
比如下面这个函数中的变量a,只能在函数内部访问到,在函数外面不能找到a的定义。
其他计算机语言中,{}块级作用域。
而js中比较简单没有块级作用域,只有函数能关住变量。
 

1 function fun(){
2 var a = 1;
3 console.log(a);
4 }
5 fun();
6 console.log(a);
 

1.10 全局变量和局部变量

局部变量:在某个作用域定义的变量,就是局部变量。局部变量只能在该作用域内使用,其他任何地方都不是使用。
全局变量:从广义上来说,全局变量也是局部变量。在全局范围内定义的变量,叫做全局变量。也就是在全局范围内都可以访问的到这个变量。
 

1 var a = 1;
2 function fun(){
3 var b = 2;
4 console.log(b);
5 }

7 console.log(a);
8 console.log(b);
 
变量声明的原理:全局变量,在全局定义之后,会永久存在,任何时候,任何位置访问,都能够找到它。局部变量定义在函数内部的,函数定义的过程,并没有真正的去定义这个局部变量,只有在执行函数的时候,才会立即定义这个局部变量,执行完之后,变量就被立即销毁了,在其他的地方访问变量的时候,找不到这个变量,所以会有一个引用错误,变量未定义。

1.11 作用域链

指的是我们变量查找的一个规律:我们可以在不同的作用域内使用相同的标识符去命名变量。我们在使用一个变量的时候,需要找到匹配的标识符,我们有重复的,用哪一个?如果在当前作用域有这个变量,就直接使用,如果当前作用域没有这个变量定义,会一层一层的从本层往外依次查找,遇到第一个就直接使用。类似于就近原则。
 

1 var a = 1;
2 function fun1(){
3 var a = 2 ;
4 function fun2(){
5 var a = 3;
6 console.log(a);//本层a有定义,直接使用本层的定义a = 3
7 function fun3(){
8 console.log(a);//本层没有定义,但是外层有定义,a = 3.
9 }
10 fun3();
11 }
12 fun2();
13 }
14 fun1();
15 console.log(a);
 
当遇见一个变量时,JS引擎会从其所在的作用域依次向外层查找,查找会在找到第一个匹配的标识符的时候停止。在多层嵌套的作用域中可以定义同名的标识符,发生“遮蔽效应”。
如果变量声明时,不写var关键字,计算机会自动在全局作用域内给它进行一个声明,局部变量就强制性的变成了全局变量。这种情况是不合理,会造成一个全局变量的污染。所以,定义变量必须写var关键字。
 

1 var a = 1;
2 //var a = 2;
3 //var a = 3;
4 function fun1(){
5 a = 2 ;
6 function fun2(){
7 a = 3;
8 console.log(a);//本层a没有定义变成了全局变量
9 function fun3(){
10 console.log(a);//本层没有定义,使用全局a = 3
11 }
12 fun3();
13 }
14 fun2();
15 }
16 fun1();
17 console.log(a);
 

1.12 形式参数是局部变量

形式参数只能在函数内部使用,形式参数是局部变量。
1 function fun(a,b){
2 console.log(a);
3 console.log(b);
4 }
5 fun(3,4);
6 console.log(a);
7 console.log(b);
 

1.13 全局变量的作用

①传递作用:在不同函数间,全局变量可以用于传递作用(信号量),所有函数都可以操作这个全局变量。全局变量不会重置也不清空。
 

1 var a = 1;
2 function jia(){
3 console.log( ++ a);
4 }

6 function jian(){
7 console.log(-- a);
8 }

10 jian();//0
11 jia();//1
12 jia();//2
13 jia();//3
14 jian();//2
 
②通信作用。一个函数可以多次调用,可以将全局变量累加(每次都是用新值参与函数的执行)。(函数间的通信)
也不会清空,或者重置。
 

1 var a = 1;
2 function jia(){
3 a += 4;
4 console.log(a);
5 }

7 jia(); //5
8 jia(); //9
 
 
爱创课堂是一家专门做前端培训的机构,由百度高级工程师,<javascript设计模式>作者张容铭老师亲自授课,全程20个项目实战。我们前端课程的五大优势:
1. 名师亲自授课,课程无缝隙对接企业
2. 免费学习一周
3. 签订就业协议,目前学员平均就业薪资12K
4. 采取小班教学模式(一个班20—30人)
5. :与中国石油,中国电信,软通等知名企业合作,进行企业内训,并进行学员就业推荐
 
扫描下方二维码或搜索微信公众号:icketang  
关注并回复:js  领取 js基础全套视频教程+课堂笔记+案例

 
访问:http://www.icketang.com/?zh获取更多信息。