JavaScript基本数据类型(6)- 函数(function)+底层运行机制


本章是讲解函数的重点章节,不仅详细描述了函数的语法,构成,形参和实参,还讲解了底层的运行机制,栈内存和堆内存


函数数据类型 function

函数就是一个方法或者一个功能体,函数就是把实现某个功能的代码放到一起,进行封装,以后想要操作或者实现这个功能,主需要调用我们封装的函数(减少页面中重复的代码,提高代码的使用率,低耦合高内聚)

耦合度:比如有对夫妻,妻子非常的依赖丈夫,没有丈夫就活不下去,这就是高耦合的表现。如果一个函数只能在某些很极端的条件下才能使用,或者搬到另外一个地方用就用不了,通用性和移植性比较差那就是高耦合函数

比如下面我们把函数比喻成一个微波炉

  1. 微波炉要放什么食物(形参)

  2. 微波炉怎么加热食物(实现功能)

  3. 食物加热后变成什么样(return值)

    function WeiBoRu(food) {
        console.log('加热食物中~~');
        finallyFood = String(food) + 'ok';
        return finallyFood
    }
    
    console.log(WeiBoRu('牛奶'));
    
    // 加热食物中~~ 
    // 牛奶ok
    
形参和实参

  1. 形参实参基本形式

    // 定义在函数体内的参数叫做形参
    function fn([形参1, 形参2, ...]) {
    	value = 形参1 + 形参2
    	return value
    }
    
    // 调用函数传入的参数叫做实参, 10 和 20 都是实参
    fn(10, 20)
    
  2. 形参和实参的关系

    1. 形参数 大于 实参数字

      function hello(num1, num2) {
          return num1 + num2
      }
      
      hello(1, 2, 3, 4);
      	// 结果是3, 后面的 3 和 4 都会被抛弃
      
    2. 形参数 小于 实参数字

      function hello(num1, num2) {
          alert(num1 + num2)
      }
      
      hello(1);
      	// 输出 NaN,num1是1,num2是undefined,数字+undefined = NaN
      
arguments

当我们不知道用户传入多少个实参,可以在函数内使用一个关键字 arguments,其包含所有实参的一个伪数组

function fn(value) {
	console.log(value);
	console.log(arguments)
}

// 调用,传入多个参数
fn(1, 2, 3, 4, 5, 6)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bCyndtfG-1576572268859)(assets/1576488096722.png)]

伪数组: 具有数组的 length 方法,能获得长度,但是arguments原型是Object,没有数组的方法

有名/匿名函数

  1. 有名函数

    function fn(a, b) {
    	console.log(a, b)
    }
    
  2. 匿名函数(函数表达式和立即执行函数)

    // 1.函数表达式
    let fn = function() {}
    document.document.onclick() = function() {}
    
    // 2. 立即执行函数
    (function(a, b){}(a, b));
    (function(a, b){})(a, b);
    
函数底层运行机制
  1. 创建函数(凡是引用数据类型,都会创建堆内存),浏览器开辟一块全新的堆堆存,并把函数体内的代码以字符串的形式保存在堆中

  2. 运行函数

    1. 运行函数会开辟一块全新的栈内存用来自上而下执行函数(代码都是在中执行的)
    2. 基本数据类型比较简单,所以会直接在函数执行的栈内存中存放
    3. 这个栈内存有属于自己的私有作用域,外部是访问不到里面的变量
    4. 函数运行结束后会return一个值,并传给外部接收的变量(没设置则为undefined)
    5. VO阶段属于变量值存储阶段,AO属于函数执行阶段

    在这里插入图片描述

li按钮下表经典题

为什么用for循环给每个按钮注册点击事件,点击 i 之后的值一直是5

<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>

let btnList = document.querySelectorAll('button');

for (var i = 0; i < btnList.length; i++) {
    btnList[i].addEventListener('click', function () {
        console.log(this.i);
    })
}

在这里插入图片描述

  • 原因:
    1. for 循环每次给按钮的 onclick 添加回调函数
    2. 都只是创建一个堆,并并且函数内的代码以字符串格式丢进去,并没有执行
    3. 当我们点击一个按钮的时候,回调函数会开辟一个新的私有内存栈,执行字符串里的代码
    4. 由于当前作用域没有 i 这个值,就往上一层作用域里面找,i的值已经是5了

解决方案①

给每个按钮添加一个属性,index,并把i的值赋予它

let btnList = document.querySelectorAll('button');

for (var i = 0; i < btnList.length; i++) {
    btnList[i].index = i;
    btnList[i].addEventListener('click', function () {
        console.log(this.index);
    })
}

在这里插入图片描述

任意数求和经典题

无论传入什么数,都能求和

function sum() {
    let total = null;
    for (let i in arguments) {
        let num = parseFloat(arguments[i]);		// 排除 '123aaa' 这种情况
        !isNaN(num) ? total += num : null		// 通过NaN判断是不是数字
    }
    return total
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值