【精讲】JavaScript函数

本文深入探讨JavaScript函数的各个方面,包括基础定义、函数表达式、标签函数、剩余参数的使用以及箭头函数。重点介绍了剩余参数如何处理不定数量的参数,并通过Arguments对象模拟函数重载。此外,还讨论了匿名函数、箭头函数的特性和IFEE(立即执行函数表达式)的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

函数

基础知识

函数的定义


function demo(){
    //code...
}

const square = function(number) { return number * number; };

JS不支持函数的重载,后面写的会覆盖前面的。

    function a(a,b,c){}//被覆盖了
    function a(a,b){}
    console.log(a);//f a(a,b){}

与其他语言中的函数一样,js中的函数遇到return语句就停止执行了,也就是说,return语句之后的语句都不会被执行。

如果一个函数没有return语句,那么这个函数默认返回undefined

函数表达式/标签函数

虽然上面的函数声明在语法上是一个语句,但函数也可以由函数表达式创建。这样的函数可以是匿名的;


    const square = function(number) { return number * number; };
    var x = square(4); // x gets the value 16

如果这样的函数用于字面量字符串:

用于字面量字符串时,有如下规定:

传入字面量字符串时,需要用反引号将参数包围,

如functionname `parameter`

标签函数的第一个参数是 传入参数去掉插入量剩下的字符串,

    let sum = (strs, a, b) => {
        console.log(strs); //[ '', ' + ', ' = ' ] 所有字符串字面量组成的数组
        console.log(a); //85 插值
        console.log(b); //100 插值
    }
    let a = 85;
    let b = 100;
    sum `${a} + ${b} = `;

剩余参数(重点)

剩余参数用于给函数传递不确定个数的参数,它实现的形式是数组,所以可以使用数组的方法。

对于一个函数来说,只能接受一个剩余参数变量,如果这个函数有多个变量,那么剩余参数必须是最后一个变量。

	function add(a,b,c,...args){
		//这是符合语法规则的
	}
```js

```js
	function add(...args, ...vals){
		//这是不符合语法规则的
	}
	
	function demo(...args,a){
		//这也是不符合语法规则的
	}	

…args和args的区别

	function demo(...args){
		console,log(...args);
		//...args输出的是字符串 ‘1 2 3 4’
		console.log(args);
		//args输出的是array对象
	}

Argument对象

arguments 是一个对应于传递给函数的参数的类数组对象。

每一个函数都会有这个数组对象,这个对象记录了函数接收的所有参数。

因为它的原型是Objecter而不是Array,所以它不是一个真正的数组,故称“类数组对象”,所以不能使用数组的方法。

用Arguments参数模拟函数重载

由于js中是没有重载这一概念的,如果要实现重载的时候,可以使用argument参数进行模拟。

原理:用if判断参数的个数,然后执行不同的代码;

    function demo(){
        if(argument.length === 1){
            console.log(argument[0]);
        }else if(argument.length === 2){
            console.log(argument[0]+argument[1]);
        }
        /*....*/
    }
    demo(1);    //1
    demo(1,2)   //3

Arguments对象中的callee与caller

callee是arguements对象中的一个属性,用于返回当前函数体正在执行的函数。

但在ES5的严格模式下,这两个属性已经被废除了,即使没有使用严格模式,这一属性也有其他的替代方法。

并且这两个属性会影响后续开发的优化。因此不推荐使用。

Arguments 与 剩余参数

剩余参数的表型形式是数组,所以它可以使用各种数组方法。

    function multi(...a){
        console.log(a); //Array(5) [1, 6, 9, 7, 6]
        return a.reduce((p,c)=>(p*c));
    }
    multi(1,6,9,7,6);
function add(...adder) {
    console.log(arguments);//Argument(4) [1,2,3,1]
    return adder.reduce((p, c) =>  (p * c ))
    
}
add(1, 2, 3, 1);

Arguments参数可变性

arguments的参数是可以设置的,但是并不会影响函数的结果。

    function multi(...a){
    arguments[0]=6;
    console.log(arguments);//Argument(2) [6,6] 发生了改变
    // arguments[0];
    return a.reduce((p,c)=>(p*c));
}
multi(1,6);//仍然是6

Arguments性能问题

对参数使用slice会阻止某些JavaScript引擎中的优化 (比如 V8 - 更多信息)。如果你关心性能,尝试通过遍历arguments对象来构造一个新的数组。另一种方法是使用被忽视的Array构造函数作为一个函数:

var args = (arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments));

详情请戳:https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments

匿名函数

匿名函数顾名思义就是没有名字的函数。

    var arr = [1,2,3];
    arr.map((cur)=>(cur*2));

(cur)=>(cur*2)就是一个匿名箭头函数

箭头函数

箭头函数是匿名函数的一种,他能让你的函数写的更简洁,更优雅。

let fn =()=>{//coding}

这样的函数常作为callback函数回调使用,如array的reduce、map函数都要求传入一个callback function作为参数。

	let arr = [1,2,3,4,5,6];
	arr.

箭头函数没有自己的this指针,所以箭头函数内使用的this指针默认继承父作用域的this指针,给出证明如下:

    var a =0;
    function foo() {
        var a =50;
    
        let show = ()=> {
            var a = 55;
            console.log(this.a);
        }
        show();
    }
    
    let obj={
        a:666,
    }

	foo();//输出:0

箭头函数的this继承父作用域foo(),而这个作用域是定义在全局windows下的,所以foo作用域内的this指针指向全局windows,故箭头函数内的指针也指向全局windows。

如果此时用call方法改变foo函数的this指针指向。那么箭头函数内的this指针指向也会发生变化,由此可以证明:箭头函数内的this指针指向继承父作用域的this指针指向。

	foo.call(obj);//把foo函数的this指向obj
	//输出:666

可以看到,我们修改了foo内的this指向,导致了箭头函数show的输出的a变成了obj里面的a属性。

由此可以证明,箭头函数内的this指向继承父作用域,且随着父作用域的this指向改变而改变

IFEE 立即执行函数

立即执行函数,顾名思义,在定义的时候就会被调用的函数就是立即执行函数。

立即执行函数时匿名函数的一种,它具有自己的作用域,因此可以避免污染全局。

立即执行函数如何定义呢?

立即执行函数:(function(){function body})(parameter);

    (function(){
        //coding...
    })();

    (function(){}());
    //其他定义

    !function(){}();
    ~function(){}();
    +function(){}();
    void function(){}();
    -function(){}();

避免污染全局的一个例子

一些变量只需要使用一次,之后便不会再调用了,这样的变量适合放在立即执行函数中去操作。


    (function(){
    var [year,month,day]=[2022,3,25];
    /*通过一些代码让获取日期信息,这里直接进行赋值*/
    document.body.innerHTML=`现在时间是${year}${month}${day}`}());

在这里插入图片描述

这样一来,year、month、day这些变量名就不会跑到全局区域。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值