javascript中函数的封装以及作用域预解析

1.认识函数:

            函数是js中的一种数据类型,是一个复杂(引用)数据类型,单词是function

            曾经给一个变量可以赋值的有:字符串类型、布尔类型、数值类型等,那既然函数是一个数据类型,自然也是可以赋值给变量。

            要想理解函数,你可以这样理解:

                我们可以把函数看作是一个盒子,在这个盒子中可以写很多很多的代码,当你需要用到这段代码的时候我们只需要找到这个盒子即可。

 2.封装:

         1.  把一段代码放到一个盒子中,这种行为我们一般就叫做封装,装到盒子中其实装到函数中,所以把代码放到函数中这种行为我们一般叫做封装函数

        2.在程序中使用函数必须要做的2件事情

            1).如何把一段代码放到盒子中(函数中)========定义函数

            2).如何找到这个盒子(找到这个函数),找函数的目的是为了执行盒子中的代码====调用函数

3.如何定义函数?

            方式一:声明式函数

                语法:function 函数名(){代码段}

                function=====这个单词是定义函数的关键字,告诉浏览器我这里要写一个函数了

                函数名====你自己随便去起(符合命名规则和规范即可)

                ()====必须写

                {}====在{}中就是你存放到这个函数中的代码片段

            方式二:赋值式函数(函数表达式)

                语法:var 变量名 = function(){代码段}

                注意点:赋值式function后面不要跟名字,这种有些语言中也叫做匿名函数

  4.如何调用函数?

            调用函数的主要目的:是为了执行函数中的代码

            语法:函数名()

      注意:无论是声明式还是赋值式,他们的调用语法都是一样的

                 声明式函数调用在前面还是后面都可以

                 赋值式函数调用在前面会报错

<script>
// 定义函数  声明式函数
    function fn1() {
        console.log('====================');
        console.log('我是fn1函数');
        console.log('====================');
    }
    // 调用函数
    fn1()
    fn1()
    // 赋值式函数
    var fn2 = function () {
        console.log('我是赋值是函数');
    }
    fn2()
    fn2()

     // fn1()
    // // 声明式函数
    // function fn1(){
    //     console.log('这是声明式函数fn1');
    // }
    // fn1()

    // fn2()
    // // 赋值式函数
    // var fn2 = function(){
    //     console.log('这是赋值式函数fn2');
    // }
    // fn2()
</script>

5.参数:

            形参:在定义函数的小括号中写的变量,这个变量仅限于函数内部使用

            实参:在调用函数的时候小括号中写的真实的数据

            实参是给形参赋值的

 注意: 参数可以写很多个,中间通过逗号隔开。

             实参给形参赋值的时候是按照从左到右的顺序依次赋值。

             当实参个数和形参个数一致的时候:我们可以保证每个形参都有值

             当实参个数比形参个数少的时候:从左到右依次赋值,后面多余的形参值执行结果为                       undefined

             当实参个数比形参多个时候,后面多出来的数据是无用的,是无意义的

             尽量保证实参个数和形参个数一致,这样一定不会出问题。

<script>
  function chengfabiao(x) {
        for (var i = 1; i <= x; i++) {
            for (var j = 1; j <= i; j++) {
                document.write(i + '*' + j + '=' + (i * j) + '&nbsp;&nbsp;&nbsp;')
            }
            document.write('<br>')
        }
    }
    // 调用阶段 小括号中9就是实参,实参会赋值给形参
    chengfabiao(9)
    document.write('==========================<br>')
    chengfabiao(3)
    document.write('==========================<br>')
    chengfabiao(5)
</script>

例子:

              封装一个函数,这个函数是用来输出任意2个数之间的所有的偶数的

 设计函数:

            1.先明确函数的功能(得到2个数之间所有的偶数)

            2.思考是否需要参数(是否有未知的可变的数据)需要参数的,而且需要2个

<script>
 //   得到的是x-y之间所有的偶数
    function fn2(x, y) {
        for (var i = x; i <= y; i++) {
            if (i % 2 === 0) {
                console.log(i);
            }
        }
    }
//这里输出100~200之间的所有偶数
    fn2(100,200)
</script>

5.函数的返回值

        返回值的语法:return 要返回的数据

        注意:返回值就是函数的结果

 return有2个作用:

        1.给调用者产出(返回)一个结果

        2.可以起到中断函数的作用(在函数执行过程中只要碰到return,那么函数就会立即停止,return后面代码不会执行)

         注意:如果不需要刻意中断,return单词最好写在函数代码块的最后面。

<script>
function fn(x, y) {
        var sum = x + y
        // 将求和的结果返回出去,给到调用者,将来调用者想怎么用就怎么用
        return sum
    }
    // 调用了fn函数,并把fn函数的返回值(结果)保存到了res变量中,此时res中其实保存的就是return之后的数据
    var res1 = fn(1, 2)
    alert(res1)
//打印到控制台
    var res2 = fn(2, 3)
    console.log(res2);
//打印到页面
    var res3 = fn(2, 3)
    document.write(res3)
</script>

6.预解析

            js是一门解释型语言(H5是一种标签语言),在真正执行代码之前,会先对代码进行通读并作解释,读过一遍之后才会放到浏览器中去执行

          预解析只解析2个东西

            1.var声明的变量(会对var声明的变量进行提前声明,但是暂时不赋值,只有到了执行阶段才会进行赋值操作)

            2.声明式函数

var声明:

1)给出以下代码:

                   var num = 10

                   console.log(num);

以上代码的执行的过程:

        1.先预解析(先通读代码)

                 读第一行:是否需要预解析(需要)

                     因为发现有var关键字,所以需要预解析,

                     这里就会告诉浏览器,这里定义了一个变量,叫做num,但是目前不赋值

                 读第二行:不需要

         2.再执行代码

                 执行第一行:num = 10,直接对num变量进行赋值操作,赋值为10

                 执行第二行:直接输出num的值即可。

         其实上面代码的执行过程如下:

             var num

             num = 10

             console.log(num);

2)给出以下代码:

              console.log(num);

              var num = 10

              console.log(num);

 以上代码执行的过程:

        1.先预解析:

            读第一行:不用预解析

            读第二行:发现有var关键字,所以需要预解析

                告诉浏览器这里创建了一个名字叫做num的变量,但是不赋值

            读第三行:不用预解析

        2.再执行代码

            执行第一行:console.log(num);

                因为在预解析阶段一定创建好了num这个变量了,但是并没有进行赋值操作,所以此时会打印出undefined

            执行第二行:num = 10

            执行第三行:console.log(num);======第二行已经赋值完成,所以输出10

        其实上面代码的执行过程可以演变成如下代码

            var num

            console.log(num);

            num = 10

            console.log(num);

        注意:如果没有预解析的话,第一句代码一定是会报错的。

            预解析这种行为我们也可以叫做变量提升(声明提前)

声明式函数:

        声明式函数的预解析(对函数名进行提前声明,并且赋值为一个函数)  

        声明式函数无论是在定义前调用还是在定义后调用都不会保存:是因为声明式函数会提前预解析的。

1)给出以下代码:

 fn()

    function fn() {

        console.log('fn函数');

    }

    fn()

以上代码的运行过程:

            1.预解析

                读第一行:不用预解析

                读第二行:是一个声明式函数,所以需要预解析

                    告诉浏览器我这里创建一个名字叫做fn的变量,并且赋值为一个函数

                读第三行:不用预解析

            2.执行

                执行第一行:fn(),因为在预解析阶段已经创造好这个函数了,所以就可以正常执行函数里边的语句

                执行第二行:在预解析阶段已经执行过了,所以直接跳过

                执行第三行:fn()=====正常调用函数,执行即可

        以上代码可以演变成如下:

            function fn(){

                console.log('fn函数');

             }

             fn()

             fn()

2)给出以下代码:

fn()

        var fn = function () {

        console.log('我是fn函数');

    }

    fn()

以上代码的运行过程:

            1.预解析阶段:

                读第一行:不需要预解析

                读第二行:因为碰到了var所以需要预解析,

                    告诉浏览器这里创造了一个名字叫做fn的变量,但是不赋值

                    所以此时:fn = undefined

                读第三行:不需要预解析

            2.执行阶段:

                执行第一行:fn()

                    因为在预解析阶段已经提前创建好了fn变量了,但是fn的值为undefined

                    所以这里fn()=undefined()

7.函数的默认值

            写默认值的目的是为了让调用的时候对这个形参赋值和不赋值都可

            如果形参中有些变量有默认值有些变量没有默认值,那么我们一般建议有默认值的形参放到最后。

            

//此时定义一个变量名为fn的函数,默认定义形参a,b的值分别为10和20 
function fn(a=10,b=20,c,d){
        console.log(a,b,c,d);
    }
//此时调用fn,输出的a为10,b为 20
fn()
//给变量a,b传递实参100,200,调用结果后发现结果为传递的值,说明函数的默认值是可以被修改的
fn(100,200,300,400)

8.模板字符串

        符号:反引号``

        特点:

            模板字符串支持换行

            可以识别变量,${变量}

9.解构赋值

        解构:

            主要作用:为了快速从数组或者对象中获取数据的一种方式

        语法:let 解构 = arr

        语法:let [变量1,变量2。。。。。] = arr

        注意:等号左边的叫做解构,右边的叫数组

        按照索引顺序,依次给解构中的变量挨个赋值。

    //定义一个数组名为arr的数组 
    let arr=[100,200,300,400]
    //进行解构
    let a=arr[0]
    let b=arr[1]
    console.log(a);
    console.log(b);

        数组怎么写,解构就怎么写,把数据换成变量即可

对于多维数组也是一样的

   //定义一个数组名为arr的多维数组
    let arr = [1, 2, [3, 4, [5, 6, [7, 8]]]]
    //假设要输出2,4,6,8的值,分别赋值为a,b,c,d;使用解构
    let a = arr[1]
    let b = arr[2][1]
    let c = arr[2][2][1]
    let d = arr[2][2][2][1]
    console.log(a);
    console.log(b);
    console.log(c);
    console.log(d);

  解构对象:

        等号右边叫对象,等号左边叫解构

        语法:let { } = 你要解构的目标

        语法:let {key1,key2,key3.....} = obj

        解构对象的时候{}中写的是键名,有时候我们可能想给键重新起一个名字

        要想给键重新起一个名字

        语法:let {key1:新名字,key2,key3.....} = obj

    //创建一个对象
    let obj={
        name:'钟离',
        age:'6400',
        height:'182',
        weight:'120',
    }
    //进行解构
    let rename =obj.name
    //得到名字钟离
    console.log(rename);

    //解构也可以将原本的键名进行修改
    let{name:wukalaka,age:reage}=obj
    //从打印结果来看,成功将其键名进行修改
    console.log(wukalaka,reage);

10.  扩展运算符

        符号:(三个点...)

        在不同的场合之下,有时候是展开功能,有时候就是合并功能

        主要作用就是为了展开或者合并数据,一般用在有数据集合或者函数的参数的地方

        数据集合:可以存储很多条数据的。(数组、对象)

    //定义一个新数组arr
    var arr1 = [100, 200, 300, 400]
    var arr2 = ['hello', 'world']
    var arr3 = [...arr1, ...arr2]
    console.log(arr3);
    console.log(...arr2);

        注意:扩展运算符号在函数中,用在形参叫做合并,收集,会收集所有的实参的,所以一般建议写在形参的最后

            用在实参:叫展开

   //在函数的形参中;...表示合并将其整合成一个数组进行输出
    function fn(...a){
        console.log(a);
    }
    fn(10,20,30,40)

11.作用域

  作用域:其实就是一个东西可以起作用、可以生效的范围,代码中谈作用域一般谈的都是变量的作用域,也就是研究一个变量可以使用的范围。
  作用域的分类:
            1.全局作用域
                你打开一个html文件,整个页面就是一个全局作用作用域,全局的单词叫做window
                定义在全局当中的变量他的生命周期:就是整个页面,只要页面不关闭。变量就会一直存在
            2.局部作用域(私有作用域)
                目前对于我们而言:只有函数才可以生成私有作用域。也就是说定义在函数内部的变量就仅限于函数内部使用。变量定义在哪个地方;作用域就在哪个区域,全局作用域最大。

  变量的3个行为:
            1.变量的定义(定义变量):带有var关键字的我们就叫做定义变量
                var num;==================算定义(只是为赋值)
                var num = 10;===========算定义(定义并赋值)
                num = 20;===============不算定义(因为没有带var关键字)
            2.访问变量:当你需要拿到这个变量的值的时候我们就叫做访问
                console.log(num);=========算访问
                num = num+10;============算访问(num+10这句话中涉及了访问)
                num++==================算访问(因为需要拿到num的值然后才行+1操作)
            3.变量的赋值:当你需要给一个变量赋值的时候
                num = num+10;=========算(将num+10的结果又重新给到了num)
                num = 200 =============算(把200这个数据给到了num)

变量在作用域中的三个机制:
            1.变量在作用域中的定义机制
                定义在哪个作用域中的变量他就属于哪一个作用域,那么该变量就只能在该作用域和后代作用域中使用,不能在父级父级作用域或者其他作用域中使用。
            2.变量在作用域中的访问机制
                当我们需要访问一个变量的值的时候,首先会现在自己的作用域查看,如果有就使用,就停止查找,如果没有就会去'父级'作用域查看,如果有就使用,就停止查找,如果还没有,就会一直一层一层'往上'查找,直到查找到全局作用域为止,如果全局依然没有,代码就报错。
            3.变量在作用域中的赋值机制
                当我们需要给一个变量赋值的时候,首先会现在自己的作用域查看有没有这个变量,如果有就赋值,停止,如果没有就去'父级'作用域查找,如果父级有变量,就赋值,停止
                如果父级依然没有,就会一直一层一层'往上'找,直到找到全局为止,如果全局依然没有这个变量,那么他会自动的把这个变量给我们创造成一个全局变量

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值