js中的函数

函数

js中的函数

函数是实现某一个功能的方法
也叫做子程序,(oop中)方法

创建函数

function 函数名(形参){
函数体(实现功能的具体js代码)
}

执行函数

函数名() ——>把创建的函数执行,而且这个函数可以执行很多次
 
每执行一次都相当于把函数体中实现功能的js代码重复执行了一遍

在真实项目中,我们一般都会把实现一个具体功能的代码封装在函数中
1、如果当前这个页面功能需要在页面中执行多次,不封装成为函数,每一次实现这个功能都需要重新把代码写一次,浪费时间;而封装在一个函数中,以后想实现多次这个功能,我们就没有必要再重新写代码了,只需要把函数重新执行即可,提高了开发效率。
2、封装在一个函数中,页面上基本就很难出现重复一样的代码了 ,减少了页面中代码的冗余度,提高了代码的重复利用率:低耦合高内聚

我们把以上特点成为函数封装(oop面向对象编程思想,需要我们掌握的就是类的继承、封装、多态)

js中函数的核心原理

函数作为js中引用数据类型中的一种,也是按照引用地址来操作的

function fn() {
var num = 1+1
num *= 20
console.log(num.toFixed(2));
}
fn()

  • 创建函数
    • 首先会在当前作用域中声明一个函数名(声明的函数名和使用var声明的变量名是一样的操作:var sum; function sum(){}; 这两个名字算重复了)
    • 浏览器首先会开辟一个新的内存空间(分配一个16进制地址),把函数体中写好的代码当做普通的字符串存储在这个内存空间中(创建一个函数如果不执行,函数没有意义)
    • 把内存空间的地址赋值给之前声明的那个函数名
  • 函数执行
    • 目的:把之前存储的实现具体功能的js代码执行
    • 1、函数执行,浏览器首先会为其开辟一个新的私有作用域(只能执行函数中之前编写的js代码)
    • 2、形参赋值
    • 3、 私有作用域中的变量提升
    • 4、把之前创建时候存储的那些js代码字符串拿到私有作用域中,然后把它们变为js表达式从上到下执行
    • 5、私有作用域是否销毁的问题

闭包小知识 
函数执行会形成一个私有的作用域,让里面的私有变量和外界互补影响(相互不干扰、外面的无法直接获取里面的变量值),此时我们可以理解为私有作用域把私有变量保护起来的,我们把这种保护机制称之为 闭包

 

栈内存

作用域(全局作用域/私有作用域):提供一个js代码执行的环境
堆内存
所有的引用数据类型,它们需要存储的内容都在堆内存中(相当于一个仓库,目的是存储信息)

  • 对象会把键值对存储进来
  • 函数会把代码当作字符串存储进来

函数中的形参和实参

形参:提供入口,需要用户执行函数的时候把需要的值传递进来,形参是个变量,用来存储和接收这些值
实参:函数执行的时候传递给形参的具体值

 1 function sum(num1,num2) { //这里的num1,num2就是形参变量(类似于var了一下)
 2 var total = num1 + num2
 3 total *= 10
 4 total = total.toFixed(2)
 5 console.log(total)
 6 }
 7 sum(2,3) //这里的2,3就是实参
 8  
 9 sum(10) // num1=10 num2=undefined 定义了形参但是执行时没有传递实参,默认实参的值是undefined
10 function sum(num1,num2) {
11 // ——>如果有一个值没有传递的话,运算会得到NaN的结果,为了保证结果不是NaN,我们为其设置一个默认的值为0
12 //——>容错处理
13 //方式1
14 num1 = typeof num1 === 'undefined' ? num1 = 0 : num1
15 num2 = typeof num2 === 'undefined' ? num2 = 0 : num2
16 //方式2
17 num1 = num1 || 0
18 num2 = num2 || 0
19  
20 var total = num1 + num2
21 total *= 10
22 total = total.toFixed(2)
23 console.log(total)
24 }
25 sum(10) // num1=10 num2=undefined 定义了形参但是执行时没有传递实参,默认实参的值是undefined

|| 或操作符的小知识点
num2 = num2 || 0 表示:如果num2 为null或undefined,则将num2 赋值0,否则num2 不变。目的是防止num2 为null或未定义的错误。
其中:||表示或操作,第一个条件为真,则结果为真而不需要执行第二个条件;否则执行第二个条件,等价于以下代码:

1 if(num2 ){
2 num2 = num2 ;
3 }else{
4 num2 = 0;
5 }

函数中的arguments

当我们不知道用户具体要传递几个值的时候(传递几个值都行),此时我们无法设置形参的个数:遇到此类需求,我们就需要使用函数内置实参集合arguments
1、arguments 只有函数才有
2、不管执行函数的时候是否传递实参,arguments天生就存在,没有传递实参ARG是个空的集合;传递了实参,ARG中就包含了所有传递的实参值。
3、不管是否设置了形参,ARG中始终存储了所有实参信息

1 function fn(){
2 for(var i = 0; i < arguments.length; i++){
3 console.log(arguments[i])
4 }
5 }
6 fn(1,2,3,4,5,6)

arguments是一个类数组集合
特点
1、以数字作为索引(属姓名),从0开始
arguments[0]
arguments[1]
2、有一个length的属性,存储的是当前几个实参的长度(传递实参的个数)
arguments.length
arguments[‘length’]

arguments.callee 存储的是当前函数本身
arguments.callee.caller 存储的是当前函数在哪执行的(宿主函数),在全局作用域执行的结果是null
arguments.callee 和arguments.callee.caller 一般真正项目中很少使用,因为在js严格模式下(use strict)不允许我们使用这俩个属性,而现在项目大部分都是基于严格模式来的

1 "use strict" //在就是代码执行之前加这句话,开启js的严格模式
2 function sum(){
3 console.log(arguments.callee.caller) //fn
4 //严格模式下会报错:Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
5 }
6 function fn(){
7 sum(10,20,'小明')
8 }
9 fn()

任意数求和

1 function sum(){
2 var total = null
3 for(var i = 0; i < arguments.length; i++){
4 var cur = Number(arguments[i]);
5 !isNaN(cur) ? total += cur : null;
6 }
7 console.log(total)
8 }
9 sum(10,20,'30','abc')

js 函数中return

闭包的保护机制导致私有作用域会保护里面的私有变量,所以我们获取不到函数里面的变量的值
返回值是函数提供的一个出口:我们如果想在外面使用函数私有的一些信息,那么就需要通过return把这些信息返回出来供外面使用

 1 function sum(){
 2 var total = null
 3 for(var i = 0; i < arguments.length; i++){
 4 var cur = Number(arguments[i]);
 5 !isNaN(cur) ? total += cur : null;
 6 }
 7 return total //return后面跟着的都是值(返回的都是值):此处不是把total变量返回,而是把total存储的值返回而已
 8 }
 9 var total= sum(10,20)//=>外面是全局下的total和函数中的total没有必然联系
10 console.log(sum(10,20,'30','abc'))
11 //=>sum:代表函数本身
12 //=>sum():让函数先执行,代表的是当前返回的结果(return后面是啥,相当于函数返回的是啥)
13 function fn(){
14 var total = 0
15 return
16 console.log(total)//=>在函数体中遇到return后,return后面的代码都不在执行了
17 }
18 console.log(fn())//=>如果函数中没有写return或者return后面啥也没有,默认返回的结果就是undefined

js中的匿名函数

没有名字的函数

  • 函数表达式
oBox.onclick = function(){
//把一个没有名字的函数(有名字也无所谓)作为值赋值给一个变量或者一个元素的某个事件等就叫函数表达式
}
  • 自执行函数
1 (function(n){
2 //创建函数和执行函数放在一起了,创建完成立马执行的就是字执行函数
3 })(10)
4 //自执行函数几种书写方式:符号只是控制语法规范
5 ;(function(){})()
6 ~function(){}()
7 -function(){}()
8 +function(){}()
9 !function(){}()
原文地址:https://www.cnblogs.com/tiantian9542/p/9036419.html