h5二阶段day07

1.函数的解析

函数在两个阶段分别干了啥?

内存

栈内存:基本类型(简单数据类型)

堆内存:复杂数据类型

函数是复杂数据类型,函数名在栈内存中,函数体在堆内存中

堆内存的地址会给到函数名所在的栈内存

所以复杂数据类型又叫引用类型

函数定义阶段:

function test(形参){执行的代码}

var test=function(形参){执行的代码}

1.在堆内存中开辟一个空间,栈内存开一个新空间存函数名

2.把函数体内的代码一模一样的存储到这个空间内

3.将堆内存的地址给到函数名所在的栈内存空间

函数调用阶段:

1.函数名所在的栈内存空间,按照地址找到堆内存空间 先判断栈内存空间是否存在,再看栈内存中的堆内存地址是否存在

2.在栈里面开辟一个新的空间,叫执行空间

3.在执行空间内部对形参进行赋值

4.在执行空间内,进行函数内的预解析

5.预解析完成接下来就是在执行空间内部,把函数体内的代码挨个执行一遍

6.执行完毕后,这个执行空间就会被销毁

1.函数预解析

/* 预解析

第一行不需要

第二行需要var num 声明一个变量 但是不赋值

第三行不需要 */

/* 执行

1.console.log(num)

因为在预解析的时候我们已经声明了num变量但是没有赋值,所以这里打印undefined

2.num=100

3.将100输出到控制台

console.log(num); // undefined

var num = 100;

console.log(num);

2.声明式函数进行预解析

<script> test(); function test(){ console.log('i am a function') } test(); //第一行不解析 //第二行解析 //在浏览器声明一个变量 这个变量其实就是在内存中 //开辟一个空间 然后将一个函数赋值给这个变量,也就是把内存交给这个空间 //不解析 //代码执行 //test();因为加了() 就是当作函数来调用 //预解析的时候我们已经声明了一个test变量,并且赋值了一个函数,所以这里边正常调用 //第二步因为预解析的时候已经赋值 //直接到第三步 //跟第一步一样,当作函数来调用 </script>

3.赋值式函数进行预解析

<script> // test(); var test=function(){ console.log('i am a function') } test(); /* 预解析 第一步 不预解析 第二步,告诉浏览器,声明一个变量,起名test,不赋值 第三步,不预解析 */ /* 执行 test();因为没有把函数赋值给变量,也就是不存在test,所以这里报错test is not a function */ /* 把函数赋值给test */ /* 正常把test()当作函数调用 */ </script>

4.认识作用域

<script> //作用域分类 //1.全局作用域 // 一个html文件打开或者一个.js文件,就是一个全局作用域 //全局的这个 // 2.局部作用域 // 只有函数才有局部作用域 // if else if for while switch do while 不叫向部1用域 // 作用域提供了三个机制 // 变量的定义 // 在哪个作用域下就是哪个作用域的私有变量 // 这个变量只能自己用或者后代用父级别不能用 // 变量的赋值 // 自己作用域有先给自己的 // 自己作用域没有往上找父级父级有直接赋值停止查找 // 父级没有继续向上 // 最终到window全局作用域还是没有 // 那么这个变量会被当做全局变量进行赋值 // 变量的访问 // 自己作用域有访问自己的 // 自己作用域没有向上找父亲的如果有停止然后访问 // 如果父级没有继续向上直到找到为止 // 如果最后找到window还是没有 // 那么就会返回变量is not defined // 变量的三种行为 // 变量定义的时候我们需要加上var关键字 // 函数的名字也是标识符的一种 //函数的形参 // 变量的访问 //console.log(变量名) //变量的赋值 //= += -= *= /+ %= **= //形参和实参的交互也是一种赋值 var test=100; function fn(){ var test=200; console.log(test);//200 function fn1(){ var test=300; console.log(test);//30 } fn1(); } console.log(test);//100 fn(); fn1() </script>

5.变量的定义机制

//全局作用域 //局部作用域 //定义在哪个作用域的变量,就是哪个作用域的私有变量 //能在它的作用域及后代作用域都可以使用 //不能在他的父作用域使用 var age=18; function test(){ var name1='zhnagsan' alert(age);//test是全局的子作用域 //所以,它可以是用全局的变量 } //alert(name1);// name1属于test //只能在test内部使用 及后代作用域都可以使用 // 我们现在在它的父级别使用 所以报错 test();

6.变量的访问机制

//虽然变量名一样 但是因为作用域的问题,他们并不是一个变量 var num=100; function test1(){ var num1=200; function test2(){ var num2=300; console.log(num); } test2(); } test1(); // 现在自己的作用域里边找变量 如果有用自己的 // 如果自己没有就去父级作用域查找 父亲有 停止查找 // 父亲没有问爷爷要 爷爷有 用爷爷给的 // 最高到全局作用域 window // 如果window没有 那么久提示你 num is not defined

7.变量的赋值机制

变量的赋值机制

如果自己的作用域有,就先在自己的作用域,直接赋值

如果自己的作用域没有,那么就到父级作用域内查找

这个变量,如果有直接复制如果没有继续查找

以此类推到全局作用域window 如果还没有

就把这个当做全局变量赋值

不加var就变成一个全局变量

以后声明变量,必须加上var,变量记得加var,全局变量除外

局部变量仅仅出现在函数内部

函数执行完毕,变量空间被释放

全局变量 整个文件关闭,变量的空间才会被释放

为了节约空间 声明变量,记得加var

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值