一.函数
方法:面向对象特有的,它是对象的一部分,一个对象包含属性和方法
函数:它的功能类似于方法,但是函数的写法是直接与类文件一体的,方法是包含在类文件中的,函数和类文件是一级目录
JavaScript中的函数是包含在函数的定义方式一般用 function 来声明所有函数,他不同于其它高级语言,声明的时候一般是用数据类型(int , char ,double)
1.定义函数方式一;
<script> "use strict"; function fun(x){ if(x >= 18){ return "成年人"; }else { return "未成年"; } } </script>
一旦执行到return 代表函数结束,返回结果!
如果没有执行return,函数也会返回结果,结果就是undefined
所以我们不难发现,要想JavaScript输出错误很难,从侧面也可以看出来它是一门十分随便的语言
定义函数方式之二;
<script> "use strict"; var fun = function (x) { if(x >= 18){ return "成年人"; }else { return "未成年"; } } </script>
fun(6) '未成年' fun(63) '成年人'
function(x){....}这是一个匿名函数,可以把值赋给 fun ,通过 fun 就可以调用函数
方式二和方式一的定义等价
2.参数问题
JavaScript的函数可以传任意个参数,也可以不传参~
假设不存在参数,如何规避?
可以使用手动抛出异常来判断是否传参:
<script> "use strict"; var fun = function (x) { //判断x的类型是不是数字 if(typeof x !== "number") { throw "Not a number"; } if(x >= 18){ return "成年人"; }else { return "未成年"; } } </script>
多个参数传入
arguments:是一个Js免费赠送的关键字;
代表,传递进来的所有的参数,是一个数组!
<script> "use strict"; var fun = function (x) { //判断x的类型是不是数字 console.log(`x=>${x}`); for (let i = 0; i < arguments.length; i++) { console.log(arguments[i]); } if(x >= 18){ return "成年人"; }else { return "未成年"; } } </script>
arguments包含所有的参数,我们有时候只想要多余的参数,需要排除已经使用了的参数
rest:
ES6引入的新特性,获取在函数定义外,所传入的所有参数
<script> "use strict"; var fun = function (x,y,...rest) { //判断x的类型是不是数字 console.log(`x=>${x}`); console.log(rest) if(x >= 18){ return "成年人"; }else { return "未成年"; } } </script>
rest参数必须写在最后面,必须用 ... 标识
rest也是一个数组
二.变量的作用域
(一).变量
在JavaScript中,var的定义实际上是有 作用域的。
假设在函数中声明,则在函数体外不可以使用~
1.函数的中定义的变量只在函数类,外部不能使用,否则报错
<script> function fun() { var x =1; x=x+1; } x=x+1; console.log(x); //Uncaught ReferenceError: x is not defined </script>
2.在两个函数类,定义自己的变量,但是变量名一样,不会发生冲突,因为函数内部定义的作用域只在函数内,出了函数体自动失效
<script> function fun() { var x =1; x=x+1; } function fun2() { var x= 2; x=x+1; } </script>
3.内部函数可以访问外部变量,外部不能访问函数内部变量
<script> var y =1; //全局变量 function fun() { var x =1; //局部变量 x=x+y; } var z = x+1; //全局变量 引用局部变量 console.log(z); //Uncaught ReferenceError: x is not defined </script>
4.内部变量和外部变量重名
<script> var x =1; //全局变量 function fun() { var x ='A'; //局部变量 console.log(`inner:x=${x}`); } console.log(`outsider:x=${x}`); </script>
互不影响,在外部调用则使用的是外部变量,在内部调用就使用的内部变量
原因:JavaScript对于变量的查找机制是从内向外的,函数处于内部,当他要使用的变量在自己中可以找到时,就会使用自己的,如果找不到,就会向外部找,所以,当重名的变量名内部就会屏蔽外部的
5.提升变量的作用域
<script> function fun() { var x = "x" + y; //局部变量 console.log(x); //x undefined var y = 'y'; } </script>
执行结果是:x undefined 而不是:Uncaught ReferenceError: y is not defined
说明js在执行的时候自动提升了声明作用域,但是没有提升赋值作用域
它就等同于以下代码:
<script> function fun() { var y ; var x = "x" + y; //局部变量 console.log(x); //x undefined y= 'y'; } </script>
这是js自动提升的声明作用域,所以这就是报错中很典型的声明在前,赋值在后,所以执行时不报错,但没有结果
在Java中是要报错的:未初始化错误
再后来的JavaScript程序猿都养成了习惯,规范的把所用变量的申明都放在前面,要使用变量在使用的函数段自行赋值就行了
这是规范,不是约定
<script> function fun() { var y ,x,z,k,l,m; x = "x" ; //局部变量 y= 'y'; z= 3; k = x+y; } </script>
(二.)全局函数
<script> //全局变量 x = 1; function fun() { console.log(x); } console.log(x); </script>
全局变量在函数内,外部都可以使用
1.全局对象 window
<script> var x = "xxx"; alert(x); window.alert(x); //这两个alert的弹窗弹出的结果都是一样的 </script>
默认所有的全局变量都是绑定在window对象下的
alter()这个函数本身也是一个window变量
2.函数之间的互相赋值
<script> var x = "xxx"; window.alert(x); // 弹出 xxx var new_alert =window.alert(); new_alert(x); // 弹出 xxx window.alert = function (){ // 无效函数 }; window.alert(x); // 无弹出 window.alert=new_alert; window.alert(x); // 弹出 xxx </script>
js其实只有一个全局作用域,如果一个函数内使用的变量(函数自己也可以视为变量)在函数内未找到,就会向外找,如果在全局作用域内未找到,就会报错:RefrenceError
3.规范全局变量
由于我们所有的全局变量都会绑定到我们的window上,如果不同的js文件,使用了相同的全局变量,冲突 -- 》如何能够减少冲突?
自定义一个全局变量,自定一个你自己 使用的唯一的对象,供你自己写的js代码使用
<script> var MaApplication = {}; MaApplication.name = "tiancai"; MaApplication.add = function (a, b) { return a+b; } var value=MaApplication.add(1,2); console.log(value); </script>
将自己的代码放在自己定义的唯一空间名字中,降低全局命名冲突的问题
三.局部作用域:let
1.在循环内使用 var 定义变量
<script> function fun() { for (var i = 0; i < 2; i++) { console.log(i); } console.log(i+1); //打印的是 3 说明 var 定义的变量出了循环还可以使用 } </script>
2.在循环内使用 let定义
注意:let是ES6 的新特性,解决局部作用域和全局作用域冲突的问题
<script> function fun() { for (let i = 0; i < 2; i++) { console.log(i); } console.log(i+1); //Uncaught ReferenceError: i is not defined } </script>
使用let定义的循环,外部是使用不了的,哪怕是在函数内,都不可以
所以,建议局部变量都使用let去定义
四.常量 const
在ES6 之前,怎么定义常量的呢?那些老一批的程序员使用大小写来区分常量,一般大写的就代表常量,后来的程序猿就建议不要修改大写定义的值...
例如:
var PI = " 3.14" ;
我们都知道它是一个变量,可以改变值,但是老一辈的程序猿,用大写是代表常量,所以我们都默认PI 是只读常量,不去改变它;
在ES6之后我们就引入了真正的常量定义 : const ,被这个关键字标识的变量其值不可变
<script> const PI = '3.14'; PI =1; //爆红,报错:常量不能改变 </script>