函数的相关内容

函数概述

函数相当于一个代码空间,他里面可以存储一些代码片段,一般我们会将一些功能性代码抽取放入到函数内,这样的操作就是封装。核心就是利用函数来减少冗余代码的出现,形成对应的复用。

函数的分类

  • 系统函数:(系统本身就写好的,只需要调用console.log()属于全局窗口的windows)
  • 内置函数:属于对应的内置对象的函数(Math.pow()...)
  • 自定义函数:自己定义的函数(自己封装抽取的代码)

函数的定义(自定义的函数创建)

使用function关键来定义

匿名创建(没有名字 无法被复用)

        
        //自执行函数 自己执行 准备工作的执行(框架的封装)
        //前面()表示他是一个整体 后面()表示执行这个函数
        (function () {
            console.log('hello')
        })()

具名函数(有名字的函数 必须调用才会执行 具备复用价值)

        // 具名函数
       /* 
            function 函数名(参数....) {
                执行的代码
            } 
        */
        function fn(){
            console.log("hello world");
        }
        fn()
        
        //结合匿名函数来声明具名函数
        var a = function(){
            console.log("你好");
        }
        //调用
        a()

使用对象构建的形式(使用new关键字)

        var fn1 = new Function('alert("1234")')
        fn1()

函数的参数

  • 没有实际的参数叫形参  用于定义(随便写)
  • 有实际值的参数叫实参  用于传递
        //传递参数
        //计算俩数之和 在函数声明的时候他传递的参数是形参(变量名)       

         function sum(a, b) {
            console.log(a + b)
        }
        //调用执行 传递的参数是实参 一定有对应的值
        sum(1, 2)
        //new Function的方式传递参数
        var sum1 = new Function('a', 'b', 'alert(a+b)')
        sum1(1, 2)

注意事项:js允许少传参 必须这个参数没有被使用到(没有函数的调用)否则会出现错误

练习

传递一个数 判断是否回文 

function isPalindrome(n) {
//判断当前是否为数值
if(isNaN(Number(n))){
//错误提示
// console.error('当前输入的内容出错')
//抛出一个新的错误 底下的内容不会被执行
throw new Error('当前输入的内容出错')
}
//个数为0不可能是回文数
if(n%10==0 && n!=0){
console.log('这个数不是回文数')
}else if (n < 10 && n >= 0) { //小于10 大于0的数为回文
console.log('当前数为回文数')
} else {
//需要将当前这个数进行反转
var x = n
var y = 0
//反转操作
while (x > y) {
y = y * 10 + x % 10
x = parseInt(x / 10)
}
//偶数情况下
if (x == y) {
console.log('当前数为回文数')
} else if (x == parseInt(y / 10)) {
console.log('当前数为回文数')
} else {
console.log('这个数不是回文数')
}
}
}
isPalindrome(prompt('输入数值进行判断'))

传入一个数判断是否是水仙花数

function isNarcissusNumber(number){
//判断当前是否为数值
if(isNaN(Number(n))){
//错误提示
// console.error('当前输入的内容出错')
//抛出一个新的错误 底下的内容不会被执行
throw new Error('当前输入的内容出错')
}
//验证
if(Math.pow(number%10,3)+Math.pow(parseInt(number/10%10),3)+Math.pow(parseInt(n
umber/100),3)==number){
console.log('当前数为水仙花数')
}else{
console.log('当前数不是水仙花数')
}
}
isNarcissusNumber(prompt('输入数值进行判断'))

函数考虑其复用性的同时,必须要考虑多种情况的产生 

函数的执行过程 

预编译过程

var关键修饰的变量会预编译

console.log(a) //undefuned
var a = 10
console.log(a) //10

function也会发生预编译

fn()  //也能执行  function会被预编译
function fn(){
    console.log('测试')
}
console.log(fn1)    //undefined
fn1()    //var关键词预编译不会读取赋值操作 报错 is not a function
//第二种具名函数的定义
var fn1 = function(){
    console.log('test')
}

 执行过程

函数声明会发生预编译 调用的时候会发生什么操作

他会去寻找对应的堆空间的函数引用

然后再将他推入执行栈中 进行执行

在执行栈中会打开对应的函数内的代码进行执行

当他执行完以后 那么gc就会将他回收(可达性)

回收过程

gc是一个垃圾回收机制(用于回收当前没有被使用的变量)

 主回收器        Major gc (常用的回收大的对象 明显)

 副回收器         Minor gc (回收碎片化内容 使用频繁)

回收机制

标记清除(设置true false标记)

引用计算(引用操作进行++)

JavaScript的程序预编译过程

预编译过程属于编译之前做的事情 他会进行如下操作

  • 优先编译function
  • 优先编译变量(不会进行赋值操作的)
console.log(a); //undefined
// a() //报错 a 不是一个函数 预编译不会编译赋值操作
//调用 方法名(实际的参数)
fn()
//具名函数
/* function 函数名(参数,...){
执行的代码
} */
function fn(){
console.log('hello world');
}
//具名函数的第二种写法
var a = function(){
console.log('你好');
}
//调用
a()
//在JavaScript中程序运行有个预编译过程
//他会先去加载对应的方法 function修饰的方法 加载对应的变量 var修饰的变量(并不会优先编译
赋值)

练习
传入俩个数 打印他们间最大的

function max(number1,number2){
if (typeof number1 != "number" || typeof number2 != "number") {
// console.error('输入出错');
//抛出新的错误
throw new Error('输入出错') //当程序报错 底下的所有内容将不会再执行
}
//比对最大值
var maxValue = number1>number2?number1:number2
console.log(maxValue)
}
max(1,2)//打印2

return 关键词
return是用于在函数中返回对应的结果的,默认情况下函数return undefined。当return完那么对应的函数就执行就结束了。

function 方法名(形参1,形参2,....){
相关操作
return 数据
}

示例
计算俩个数的和 将这个和返回

//return 后面的内容是不会执行的
function sum(n1, n2) {
console.log('之前执行的')
return n1 + n2
console.log('之后执行的')
}
var result = sum(1, 2)
console.log(result)
// 当你没有return关键词 他也会返回对应的数据 他的返回是在程序执行完以后 返回的值undefined
function fn(){
console.log('程序运行');
return; //没有指定对应的数据 相当没有return 相当于将return关键词放在最后面
console.log('结束');
}
console.log(fn());

return的特点

  1. 他会结束对应的函数,在本身这个函数函数内容 执行了return后面的内容将不会再执行了
  2. 我们一般在程序的结尾返回对应的数据
  3. 也可以利用对应的retrun的特性帮助我们来对应的函数
function sum(number1,number2){
//如果当前传递的数不是数值 那么就结束这个函数
if(typeof number1 != 'number' || typeof number2 != 'number'){
return
}
return number1+number2
}

总结

  • break跳出循环和switch不会结束function
  • continue 只能用于循环中 跳过本次循环 进入下一次
  • return 关键词只是结束当前的函数 返回对应的数据(放在最后)
  • throw new Error 抛出错误是结束整个程序

arguments

arguments是一个参数列表其实是一个伪数组(伪装的数组 有数组的一些特性 但不是数组(不具备数组的方法))。他可以用于获取所有的参数(传递的参数)

function fn() {
//所有的函数都具备arguments arguments特殊的值里面包含所有的参数
console.log(arguments)
//获取arguments里面的参数的第一个 arguments[下标] 来获取对应的下标的值
console.log(arguments[0]);
//查询当前arguments的长度 arguments.length
console.log(arguments.length);
}
//对应的下标从0开始 0表示第一个 最大值 对应的长度-1 length 当前的个数-1
fn(1, 2, 3, 4, 5)

示例
传入任意的数值来取出它的和

function sum(){
//获取所有的参数 数值
var result = 0
//遍历arguments里面的所有的数值
for(var i =0;i<arguments.length;i++){
result += arguments[i]
}
return result
}
console.log(sum(1,2,3,4,5))

使用arguments来获取对应的值的时候 我们一般不写形参

arguments的属性及方法

  • length属性 用于获取对应的传入参数个数
  • callee 方法 指向当前的函数

arguments访问对应的参数使用下标访问

  • 下标从0开始 到 arguments.length-1结束
  • 0表示是第一个参数,那么5表示第六个参数 x表示x+1个参数
  • 省略对应的形参 直接传入实参 在函数中使用arguments来接收的对应的实参

作用域及作用域链
作用域概述:
一个变量的作用范围称为作用域,在全局声明的变量就是全局作用域,在函数内容声明的变量它的作用域就是局部作用域(仅在当前函数内可用 函数作用域)

var a = 10 //全局作用域
function fn(){
var a = 20 //局部作用域
var b = 30
}
fn()
console.log(a)//10
console.log(b) //b is not defined

在全局中不能访问局部作用域的变量 

作用域链

作用域链就是逐层向上查找对应的作用域(变量声明)形成的链子,如果没有找到那么就会报错。

var a = 10
function fn(){
console.log(a)//undefinde
var a = 20 //局部变量赋值
function fn1(){
console.log(a) //20
function fn2(){
console.log(a)//20
}
fn2()
}
fn1()
}
fn()

 

console.log(a)//undefinde
var a = 10
function fn(){
// a = undefined
a = 20 //局部变量赋值
console.log(a) //局部变量打印
var a = 30 //局部作用域 var修饰关键进行预编译
}
function fn1(){
a = 40 //全局作用域
var b = 30
console.log(a+b)
}
function fn2(){
//预编译
console.log(a) //undefined
var a = 50
}
fn1()//70
console.log(a)//40
fn()//20
console.log(a)//40
fn2()//undefinde
console.log(a)//40
  • var 关键词会进行变量提升
  • 只要是在function中使用var关键词声明那么这个变量就是局部变量 那么在这个里面使用到所有这个变量都是指向这个局部变量
  • 如果在function中没有使用var关键词声明那么这个变量就是全局变量 

函数的嵌套
函数是可以互相嵌套的

function fn(){
function fn1(){
console.log('hello')
//fn(3) //报错
}
function fn2(){
console.log('hello')
function fn3(){
console.log('hello')
}
}
fn1()
console.log('world')
}
fn() //hello world

在函数内部可以定义函数和调用的函数 函数内部不能调用优先级比自己要低的


事件驱动

事件驱动就是说通过触发一个行为执行对应的函数,这个被称为事件驱动

获取输入框的值

html准备

<input type="text" id="input"><button id="btn">点击按钮</button>

当点击按钮的时候打印输入框的值
1.获取按钮 

var btn = document.getElementById('btn')

 2.点击按钮 触发对应的事件 来执行对应的函数 (不需要手动调用的)

btn.onclick = fn

3.在函数内打印input框中的内容

  • 获取输入框
  • 拿到输入框的值
function fn(){
//获取输入框
var input = document.getElementById('input')
//获取输入框的值
var value = input.value
console.log(value)
}

 

简单的一个dom操作

  • 通过id获取对应的dom元素(标签)
  • document.getElementById('id名字')
var 变量 = document.getElementById('对应的标签的id属性')

给对应的变量添加点击事件

变量名.onclick = 处理函数

简单示例

<div id='content'>点击</div>
<input type="text" id="myInput"> <button id="btn">点击按钮获取input显示的值
</button>
<script>
//获取对应的div 根据id获取
var content = document.getElementById('content')
//给对应的div添加事件 由事件触发的函数被称为事件驱动
content.onclick = function () {
alert('hello')
}
//1.获取按钮
var btn = document.getElementById('btn')
//2.给按钮添加点击事件
function hello(){
//3.在点击事件执行的函数里面获取对应的input的内容
//3.1 获取input
var myInput = document.getElementById('myInput')
//3.2 再获取里面的内容 value属性 获取input的显示内容 也可以进行设置
console.log(myInput.value);
}
btn.onclick = hello
</script>

递归(Ologn)

递归是一个算法,算术其实就是固定的套路,递归算法是为了降低时间复杂度提高效率所设计的算法,他可以完成所有循环可以做的事情。

递归的用途 (可以在不知道层级的情况下走到底)

  • 文件目录遍历
  • DFS查找
  • 多级对象分析合并
  • 深拷贝
  • ...

递归的流程

  • 初始值 (不变的值)
  • 规律
  • 自己调自己

示例

function 函数名(参数){
if(条件){
初始值 进行返回
}else{
规则值 返回值 自己调用自己
}
}


问第100个位置的值的什么 2 4 6 8 10 12 14 ... 当前值 = 上一个值 + 2

function fn(n){
if(n == 1){ //没有规律的
return 2
}else{ //有规律的 自己调用自己
return fn(n-1) + 2
}
}
console.log(fn(100))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值