函数(下)

■教学目标

能够说出预解析的概念(其实就是告诉你js语法执行流程

能够说出作用域的概念(js变量哪里可以用

能够说出作用域链的概念&特性(主要特性

■函数(下)

一、预解析(script执行过程)

明确需求

说明:上一讲发现发现定义函数有两种方式,声明式(随意调用)和赋值式(必须后调用)

// 声明式
fn1(); 
function fn1() {
    console.log('hello,webopenfather')
}
fn1();
fn1(); 

// 赋值式
// fn2();
var fn2 = function() {
    console.log('hello,webopenfather2')
};
fn2(); 

思考:为什么声明式可以先调用,赋值式不行

回答:和js底层代码的执行流程相关(专业术语叫预解析

执行流程

  • 预解析( JS代码执行流程
  • 规则:
1 读取第一个script标签
2 编译(检查语法、声明变量、声明函数、代码优化等
3 执行

以此类推...
  • 举例: var i = 2;console.log(i);
1 读取第一个script标签
2 编译(检查语法、声明变量、声明函数、代码优化等
var i
3 执行
i = 2
console.log(i);

练习:验证执行流程

  • a. 执行流程验证1
console.log(num)  // ????    num未定义

/*
1 读取第一个script标签
2 编译(检查语法、声明变量、声明函数、代码优化等
3 执行
console.log(num)
*/
  • b. 执行流程验证2
console.log(num)  //  ???   undefined
var num = 2;   
console.log(num)   // 		 2

/*
1 读取第一个script标签
2 编译(检查语法、声明变量、声明函数、代码优化等
var num 
3 执行
console.log(num)
num = 2;
console.log(num) 
*/
  • c.分析声明式函数和赋值式函数JS执行过程
//需求:定义声明式函数 fn1
fn1()
function fn1() {
    
}
fn1()

// --------------------
// 1. 读取script
// 2. 编译(检查语法、声明变量、声明函数、代码优化....
function fn1() {
    
}
// 3. 执行
fn1()
fn1()
// --------------------

// 需求:定义赋值式函数 fn2
fn2()   
var fn2 = function() { //赋值式其实就是变量声明语法 只不过值是一个函数
}
fn2()   
// --------------------
// 1. 读取script
// 2. 编译(检查语法、声明变量、声明函数、代码优化....
var fn2
// 3. 执行
fn2()   //  fn2 它 undefined
fn2 = function() { //赋值式其实就是变量声明语法 只不过值是一个函数
}
fn2()  
// --------------------
  • d. 声明式函数先调用后声明必须写在同一个script标签里面
<script>
console.log(fn)    // 直接报错

/*
1. 读script
2. 编译
3. 执行
console.log(fn)
*/
</script>
<script>
function fn() {

}
</script>

练习

fn()			   // 打印 我是 fn 函数
console.log(num)  // 结果?  undefined

function fn() {
  console.log('我是 fn 函数')
}

var num = 100


/*
编译
function fn() {
  console.log('我是 fn 函数')
}
var num 
执行
fn()
console.log(num) 
 num = 100
*/

小总结

预解析是什么:js执行流程

预解析执行流程:

1. 读取第一个script
2. 编译(语法检查、声明变量、声明函数、代码优化等等
3. 执行

二、作用域!!!

明确需求

思考1:下述代码执行结果

var num = 1;
function fn() {
    var num2 = 2; 
    console.log(num)  // 1
    console.log(num2) // 2
}
fn();
console.log(num);  // 1
console.log(num2); // 逻辑上是2  但是吗?     num2 is not defined

思考2:JS代码中的变量可以在任何地方使用/输出吗?

回答:不可以

思考:为什么?

回答:因为JS作用域

相关概念(作用域/局部/全局)

  • 作用域:JS变量可以用的区域

  • 局部

局部变量:指函数体内声明的变量
    特性:仅函数体内使用(函数调用完毕销毁   生命周期
  • 全局
全局变量:指函数体外声明的变量
   特性:全局都可以使用(网页关闭销毁   生命周期

画出所有作用域

  • 题目1

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

<script>
/*
读取一个script 
编译
var num
执行
num = 111;

*/
var num = 111;

console.log(num);
</script>
<script>
console.log(num);
</script>
<script>
console.log(num);
</script>
  • 题目2

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

<script>
var num = 111;

function fn() {
	var num2 = 222;
}

console.log(num);
</script>
<script>
console.log(num);
</script>
<script>
console.log(num);
</script>
  • 题目3:

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

<script>

function fn1() {
     
}

function fn2() {
    
}
// 脚下留心:
// 你在【全局作用域】定义变量大家都可以用(你被锁在大房子里面 -> 所有小房子都可以进)
// 你在【fn1作用域】定义变量问fn2作用域能用吗,不能(你被锁在小房子里面->进不了其他房子)
</script>
  • 题目4:思考下述代码运行结果
<script>
var num = 111; 	    // 声明全局变量

function fn() {
	var num2 = 222;  // 声明局部变量
}
fn()

console.log(num);  // 结果:111
console.log(num2); // 结果:报错 没有定义
</script>

隐式声明

  • 隐式声明:函数体内不加var声明的变量
  • 作用:等于全局变量
  • 留心:全局有就修改、否则创建
  • 练习
<script>
var num = 111;       // 全局变量

function fn() {
	var num2 = 222;  // 局部变量
}
fn() 

console.log(num);  // 结果:111
console.log(num2); // 结果:报错
</script>
  • 练习:思考下述代码结果,为什么?

案例1

<script>
var num = 111;   // 函数体外面,全局变量

function fn() {
 var num2 = 222; // 函数体内,局部变量
 alert(num)		 // 弹111
 alert(num2)     // 弹222
}

fn();
alert(num)      // 弹全局  能
alert(num2)     // 弹局部  不能
</script>

案例2

<script>
var num = 111;  // 全局变量

function fn() {
 num = 222;	   // 全局变量(隐式创建
 alert(num)	   // 222
}

fn();
alert(num)      // 222
</script>

案例3

<script>
var num = 111;      	 //   全局变量  dataUpdate

function fn() {
	var num2 = 222;		  //  局部变量
	num = 'dataUpdate';   //  隐式全局变量、修改

}

fn(); 
alert(num)   // dataUpdate
alert(num2)  // 报错
</script>

小总结

作用域:JS变量可以使用区域

全局

全局变量:函数体外声明、函数体内不加var声明
生命周期:网页运行产生、网页关闭

局部

局部变量:函数体内加var
生命周期:函数调用创建、调用关闭销毁

三、作用域链!!!

明确需求

  • 思考下述代码输出结果

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

  • 思考:上述代码1w最终改的是谁? 1 2 3

概念

概念:多个作用域的集合

特性!!!:

当变量没加var时,会去上一级作用域中找【同名 && 带var】
找到了 - 直接修改
找不到 - 再去上一级作用域中找
一直找到顶级作用域
找到 - 直接修改
找不到 - 自己创建自己修改

画图

  • 根据概念画出【明确需求】的所有作用域 、并分析输出结果

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

10000

练习

  • 题目1
var num1 = 111; 	  // 全局变量

function fn1() {
    var num1 = 222;   // 局部变量
}

fn1();
console.log(num1);  // 结果:111
  • 题目2
var num1 = 111;

function fn1() {
    var num1 = 222;

    function fn2() {
        var num1 = 333;
    }
    fn2();
}

fn1();
console.log(num1);   // 111
  • 题目3
<script>
var num1 = 111;

function fn1() {
    num1 = 222; 
}

fn1();
console.log(num1); // 222
</script>



<script>
var num1 = 111; //

function fn1() {
    var num1 = 222;  // 

    function fn2() {
        num1 = 333; // 
    }
    fn2();
}

fn1();
console.log(num1);  // 3  3 3  111
</script>

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

小总结

作用域链是什么:多个作用域的集合

作用域特性

当变量没加var时,回去上一个作用域中找【同名&带var】
找到了 - 直接修改
找不到 - 在作用域链上找
一直找到顶级作用域
找到了 - 直接修改
找不到 - 自己创建修改

四、事件!!!

明确需求

在实战工作中,用户打开网页会有很多交互,例如:鼠标放到某个图标上出现提示,点击按钮返回顶部的

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

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

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

思考:如何实现?

回答:通过js的事件技术

div 基本结构
CSS 美化网页
JS  加特效

事件概念

事件:用户和网页的交互/动作

举例:鼠标移入、点击加入购物车、点击购买数量加1

留心:交互产生后全部都是交给函数处理

事件语法

ID属性值.事件类型 = function() {

​ // 代码

}

##事件种类

  • 鼠标
单击 onclick
双击 ondblclick
移入 onmouseover
移出 onmouseout
按下 onmousedown
松开 onmouseup
移动 onmousemove
右击 oncontextmenu    content内容   context
  • 键盘
按下 onkeydown
松开 onkeyup
  • 表单(后续讲
表单提交  onsubmit
表单重置  onreset
失去焦点  onblur
获取焦点  onfocus
下拉改变  onchange       上传头像file   下拉框select  单独记
  • 页面(后续讲
页面加载完毕执行 onload 
网页尺寸改变    onresize
网页滚动条      onscroll 

练习1

页面搞一个div100x100 背景绿色

实现

点击打印 你点我了

双击打印 你双击我了

移入打印 你移入我了

移除打印 你移除我了

移动打印 别乱动

<style>
div {
    width: 100px;
    height: 100px;
    background: green;
}
</style>
<div id="box"></div>
<script>
// 概念:用户和网页之间的交互
// 场景:加入购物车、登录等等
// 语法:ID属性值.事件类型 = function(){}

// 页面搞一个div100x100  背景绿色
// 实现
// 点击打印 你点我了
box.onclick = function() {
    console.log('你点我了')
}
// 双击打印 你双击我了
box.ondblclick = function() {
    console.log('你双击我了')
}
// 移入打印  你移入我了
box.onmouseover = function() {
    console.log('你移入我了 onmouseover')
}
// 移除打印  你移除我了
box.onmouseout = function() {
    console.log('你移除我了 onmouseout')
}
// 移动打印  别乱动
box.onmousemove = function() {
    console.log('别乱动 onmousemove')
}
</script>

练习2

第一个input输入数据

第二个input显示数据

我是第一个
<input type="text" id="input1">
<hr />
我是第二个<input type="text" id="input2">

<script>
// 监控input框按下:id属性值.onkeyup = function() {}
// 获取input框数据:id属性值.value
// 设置input框数据:id属性值.value = 值

input1.onkeyup = function() {
    // console.log('你输入数据了')
    // 1. 获取input1数据
    var val = input1.value
    // 2. 放到input2框里面
    input2.value = val
}
</script>

综合案例

- 计算两个文本框的加减乘除

  • 静态
<input type="text" id="input1" value="">
<select id="fuhao">
    <option value="+">+</option>
    <option value="-">-</option>
    <option value="*">*</option>
    <option value="/">/</option>
</select>
<input type="text" id="input2" value="">
<button id="eqBtn">=</button>
<input type="text" id="result" value="">
  • 写JS
<input type="text" id="input1" value="">
<select id="fuhao">
    <option value="+">+</option>
    <option value="-">-</option>
    <option value="*">*</option>
    <option value="/">/</option>
</select>
<input type="text" id="input2" value="">
<button id="eqBtn">=</button>
<input type="text" id="result" value="">

<script>
// 1. 给 = 绑定点击事件
// 2. 事件处理函数  1 获取input1的值 2 获取input2的值 3 获取fuhao 4 放到result里面


// 1. 给 = 绑定点击事件
eqBtn.onclick = function() {
// 2. 事件处理函数  1 获取input1的值 2 获取input2的值 3 获取fuhao 4 放到result里面
    var val1 = Number(input1.value)
    var val2 = Number(input2.value)
    var type = fuhao.value

    switch (type) {
        case '+':
            var rs = val1 + val2
            break;
        case '-':
            var rs = val1 - val2
            break;
        case '*':
            var rs = val1 * val2
            break;
        case '/':
            var rs = val1 / val2
            break;
        default:
            var rs = '有瑕疵'
            break;
    }

    result.value = rs
}
</script>

■ 作业

1 总结本周学习知识点,必须掌握能够口述【变量、parseInt 判断 循环 函数 事件】概念&语法

2 预习下周知识点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值