JavaScript之函数,变量作用域,let(局部变量),const(常量)

发布时间 2023-04-05 16:34:16作者: ~java小白~

一.函数

方法:面向对象特有的,它是对象的一部分,一个对象包含属性和方法

函数:它的功能类似于方法,但是函数的写法是直接与类文件一体的,方法是包含在类文件中的,函数和类文件是一级目录

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>