JavaScript学习笔记——函数

目录

四、函数

4.1 定义函数

4.2 参数问题

4.3 变量的作用域

4.4 方法 


往期内容

JavaScript学习笔记—— 快速入门(基本语法/数据类型快速浏览)

JavaScript学习笔记——数据类型详解

四、函数

4.1 定义函数

  • JavaScript 使用关键字 function 定义函数。
  • 函数可以通过声明定义,也可以是一个表达式

1.声明定义

  • 函数声明后不会立即执行,会在我们需要的时候调用到。
function 函数名(参数) {
  执行的代码
}

定义一个绝对值函数

    //定义函数 方式一
    //绝对值函数
    function abs(x){
        if(x>=0){
            return x;
        }else{
            return -x;
        }
    }

一旦执行到 return 代表函数结束,返回执行结果
如果没有执行 return , 函数执行完也会返回结果 undefined

2.表达式定义

  • JavaScript 函数可以通过一个表达式定义
  • 函数表达式可以存储在变量中
  • 函数存储在变量中,不需要函数名称,通常通过变量名来调用
//定义方式二 与方式一等价
    var abs=function (x){
             if(x>=0){
                 return x;
             }else{
                 return -x;
             }
    }

function(x){...} 是一个匿名函数,但可以把结果赋值给abs,通过abs就可以调用函数

4.2 参数问题

JavaScript 可以传任意个参数,也可以不传递参数

参数是否存在的问题? 假设不存在参数,如何规避?

1.手动抛出异常进行判断

function abs(x){
        if(typeof x!=='number'){
            //手动抛出异常来判断
            throw 'not a number';
        }
        if(x>=0){
            return x;
        }else{
            return -x;
        }
    }

2.arguments

arguments 是一个JS免费赠送的关键字

在函数体内可以通过arguments 对象来访问参数数组,从而获取传递给函数的每一个参数

 var abs=function (x){
        console.log("x=>"+x);
        for(var i =0;i<arguments.length;i++){
            console.log(arguments[i]);
        }
        if(x>=0){
            return x;
        }else{
            return -x;
        }
    }

arguments包含所有的参数,我们有时候想使用多余的参数来进行附加操作,需要排除已有的参数

3.rest

  • ES6 引入的新特性,获取除了已经定义的参数之外的所有参数

  • rest就是为解决传入的参数数量不一定

  • rest parameter(rest 参数) 本身就是数组,数组的相关的方法都可以用

//以前判断多余的参数
        function aaa(a,b){
            console.log("a=>"+a);
            console.log("b=>"+b);
            if(arguments.length>2){
                for(var i=2;i<arguments.length;i++){

                }
            }
        }

rest 参数必须写在最后面,必须用...标识

        function aaa(a,b,...rest){
            console.log("a=>"+a);
            console.log("b=>"+b);
            console.log(rest);
        }

4.3 变量的作用域

1.在函数体中声明,则在函数体外不可以使用

JavaScript中 var 定义变量实际是有作用域的

假设在函数体中声明,则在函数体外不可以使用( 如果非要实现的话 研究闭包)

  function ax(){
        var x=1;
        x=x+1;
    }
    x=x+2;

对于上面的代码段,函数体内定义变量x,在函数体外使用

浏览器控制台会报错 Uncaught ReferenceError: x is not defined

2.如果两个函数使用了相同的变量名,只要在函数内部就不冲突

    function ax(){
        var x=1;
        x=x+1;
        return x;
    }


    function ax2(){
        var x='a';
        x=x+1;
        return x;
    }

3.内部函数可以访问外部函数的成员,反之则不行

 function ax(){
        var x=1;
        function ax2(){
            var y=x+1;
        }
        var z=y+1;
    }

4.内部函数变量与外部函数变量重名

  • 在JavaScript中函数查找变量从自身函数开始,由内向外查找
  • 假设外部存在同名的函数变量,则内部函数会屏蔽外部函数的变量
    function ax(){
        var x=1;
        function ax2(){
            var x='A';
            console.log('inner=>'+x)
        }
        console.log('outer=>'+x)
        ax2()
    }

5.提升变量作用域

function ax(){
        var x="x "+y;
        console.log(x);
        var y='Y';
    }

执行上面的代码段ax(),浏览器控制台输出x undefined

说明JS执行引擎自动提升了y声明,但是不会提升变量y的赋值

//等价于这种定义
    function ax(){
        var y;
        var x="x "+y;
        console.log(x);
    }

这是在JS建立之初就存在的特性,养成规范:所有的变量定义都放在函数头部,便于代码维护

6.全局变量

  • 使用 var(关键字)+ 变量名(标识符) 的方式
  • 在 function 外部声明即为全局变量,否则在function声明的是局部变量
    var x=123;
    function f(){
        console.log(x);
    }
    f();
    console.log(x);

7.全局对象window

默认所有的全局变量,都会自动绑定在window对象

    var x='xxx';
    alert(x);
    alert('window:'+window.x); //默认所有的全局变量,都会自动绑定在window对象

执行上面的代码段浏览器会弹窗两次 

alert()这个函数本身也是window变量

    var x='xxx';
    window.alert(x);
    var old_alert =window.alert;
    old_alert(x);

    //手动定义一个全局变量覆盖window.alert()
    window.alert = function (){
    }
    window.alert(123) //会发现alert()失效
    
    //要恢复,把定义的变量赋值回window.alert()
    window.alert=old_alert;
    window.alert(456);

说明 JavaScript 实际上只有一个全局作用域,任何变量(函数也可视为变量)

假设没有在函数作用范围内找到,就会向外查找

 如果在全局作用域都没有找到,报错RefrenceError

window.alert(Q); //Q是不存在的变量

规范:

        由于所有的全局变量都会绑定到window上,如果不同的js文件使用了相同的全局变量,产生冲突-->如何减少冲突?

把自己的代码全部放入自己定义的唯一空间名字中,来减少全局命名冲突的问题

    //唯一全局变量
    var HA={};
    //定义全局变量
    HA.name='Zhangsan';
    HA.add=function (a,b){
        return a+b;
    }
    //把自己的代码全部放入自己定义的唯一空间名字中,来减少全局命名冲突的问题

8.局部作用域

    function aaa(){
        for(var i=0;i<3;i++){
            console.log(i);
        }
        console.log(i+1); //问题 i出了这个作用域还可以使用
    }

出现问题 i出了这个作用域还可以使用

ES6 let 关键字 解决局部作用域冲突问题

function aaa(){
        for(let i=0;i<3;i++){
            console.log(i);
        }
        console.log(i+1); //报错
    }

改成 let 定义后,在作用域外部使用就会报错,建议使用 let 定义局部作用域的变量

9.常量 

在ES6之前,全部大写字母命名的变量就是常量,建议不要修改这样的值

    var PI='3.14';
    console.log(PI);
    PI='4.31' //可以改变
    console.log(PI)

在ES6引入了常量关键字 const 

    const PI='3.14';
    console.log(PI);
    PI='4.31' //只读变量
    console.log(PI);

const 定义的变量不能被修改

4.4 方法 

1.定义方法

  • 方法就是把函数放在对象里面,对象:属性和方法

  • 方法一定带 ( )

  //定义方法
    var HA={
        name:'zhangsan',
        birth:2021,
        age:function (){
           var now=new Date().getFullYear();
           return now-this.birth;
        }
    }
    //属性
    HA.name
    //方法一定带()
    HA.age()

调用 HA 的age()方法

2.this

this代表什么?拆开上面的代码看看

function getAge(){
        //今年-出生的年
        var now=new Date().getFullYear();
        return now-this.birth;
    }
    var HA={
        nmae:'zhangsan',
        birth:2021,
        age:getAge
    };
// HA.age() ok
// getAge() NaN window对象

this无法指向的,是默认指向调用它的对象

3.apply

Function.apply(obj,args) 方法能接收两个参数

obj:这个对象将代替Function类里this对象
args:这个是数组,它将作为参数传给Function(args-->arguments)

在JS中可以控制this的指向,通过apply去指定函数指向哪个对象

getAge.apply(HA,[]);    //this 指向 HA 这个对象,参数为空

后续内容

JavaScript 学习笔记——内部对象/面向对象编程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HUA_8376

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值