JS-part2.2-预解析和作用域

二、预解析和作用域

2.1 预解析

在所有代码执行之前,对代码进行通读并解释(只是把代码当作一个文档)

当有 函数 和 变量名重名的时候,在预解析阶段以函数为准(函数的优先级更高)

扩展:报错信息
Uncaught TypeError : fn is not a function
=>要考虑,我前面的代码是不是用过fn这个变量了

预解析解释了什么?
在这里插入图片描述

1.var关键字
在这里插入图片描述

在这里插入图片描述
此时分别输出: undefined 和 100

2.声明式函数
在这里插入图片描述
在这里插入图片描述
此时都正常输出

注意:匿名式函数按var规则来解析
在这里插入图片描述

报错,因为此时fn是已定义而未赋值,是undefined,不是一个function,无法按function来执行。
在这里插入图片描述
预解析案例:
在这里插入图片描述在这里插入图片描述

!!!笔试可能会有:
1.这段代码执行情况
:执行到第二个fn报错
2.报错信息是什么:fn is not a function

预解析的无节操

1.if只决定赋值,不决定预解析;if条件不管是不是成立,里面的代码都会进行预解析

2.return后面的代码虽然不会执行,但是仍会预解析

在这里插入图片描述
if(true)输出:undefined 100
if(false)输出: undefined undefined
在这里插入图片描述

写代码的建议

通过预解析得知:

+ 函数名 不要和 变量重名
+ 声明式函数可以先调用,尽量不要先调用
+ 尽量使用 匿名函数(赋值式函数) 来定义

建议:
1.变量名
				+ 以名词为主
					+ price
					+ goods
				+ 尽可能的两个到三个单词
					+ userName
					+ userInfoAge
2.函数名
				+ 以功能为主
					+ getRandomColor()
					+ setGoodsPrice()
					+ clickHandler()

2.2 作用域

作用域:变量(变量名,函数名)生效的范围

两种:
1. 全局作用域
 	+ 打开一个页面就是一个全局作用域
 	+ 全局作用域,叫做window
 	
2. 私有作用域(局部作用域)
	+ 只有函数生成私有作用域
	+ 每一个函数就是一个私有作用域

作用域的上下级关系
	+ 你的函数写在哪一个作用域下
	+ 你就是谁的子级作用域

作用域的上下级关系是干嘛的
	+ 为了确定变量的使用范围
	+ 三个机制
		1. 变量的定义机制
			+ 有 var 关键字
			+ 声明式函数
		2. 变量的使用机制
			+ 你需要拿到某一个变量的值来使用
		3. 变量的赋值机制
			+ 一定要有赋值符号

2.3 变量的三种机制

1. 变量的定义机制

在这里插入图片描述

2. 变量的使用机制

在这里插入图片描述

例1:

在这里插入图片描述
输出200

例2:
在这里插入图片描述

输出undefined

例3:
在这里插入图片描述

也输出undefined,因为形参就相当于函数内部定义的私有变量

3. 变量的赋值机制

在这里插入图片描述

例1:

在这里插入图片描述

此时的num为全局变量

例2:
在这里插入图片描述
输出:
在这里插入图片描述

例3:
在这里插入图片描述
在这里插入图片描述

例4:
在这里插入图片描述
输出:
在这里插入图片描述

例5:
在这里插入图片描述
例6:
在这里插入图片描述
输出:
在这里插入图片描述

2.4 作用域和预解析

案例1

//案例1.1
var a = b = 20;
a = 10;
b = 10;
console.log(a);  //10
console.log(b);  //10

/*
 等于号是赋值
 => 赋值符号是从右向左赋值

 预解析
 1. var a

 代码执行
 1. b = 20
  => 变量赋值
  => 当一直到window都没有b的时候,会把b定义为全局变量
 2. a = b
  => 变量使用 和 赋值
  => 使用 的是b
  => 赋值 的是a
 3. a = 10
 4. b = 10
*/

//案例1.2
var a = b;
a = 10;
b = 10;
console.log(a);  
console.log(b);

/*
预解析
1. var a

代码执行
1. a = b
 => 变量使用 和 赋值
 => 使用 的是b,b没有这个变量
 => 赋值 的是a
 => 直接报错
*/

案例2

//案例2.1
fn();
var fn = 100;
function fn(){
    fn = 200;
}
console.log(fn);  //100

/*
    预解析
    1. var fn
    2. function fn(){}
    预解析结束时,fn是一个函数

    代码执行
        1. fn()
         => fn =200
         => 给全局的fn赋值,赋值为200
        2. fn = 100;
         => 给全局的fn赋值,赋值为100
        3. console.log(fn);
         => 100
*/

//案例2.2
fn(); //第一次执行后,把全局的fn赋值为200
fn(); //把200当作一个函数来执行,报错 fn is not a function
var fn = 100;
function fn(){
    fn = 200;
}
console.log(fn);

案例3

function fn(){
            var num = 100;

            function fun(){
	            //变量的使用和赋值
                //预解析,fun里面会预解析一个num
                //使用num的值,赋值给num
                //使用的时候,num就是undefined
                //把undefined赋值给num
                var num = num;
                console.log(num)  //undefined
            }
            fun();
        }

        fn();

2.5 预解析的阶段

1. 全局预解析

=> 会在页面打开的时候就进行了
=> 只解释属于全局的内容

例子:
在这里插入图片描述

此时不管fn()有没有执行,var a和function fn(){}都已经预解析了

2. 私有作用域预解析

=> 当函数执行的时候进行预解析
	=> 因为函数是单独进行预解析,所以在函数执行的时候,先进行形参赋值,再进行预解析
=> 函数内部的预解析,只属于函数内部

在这里插入图片描述
注: var b只有在fn()执行时才会被预解析;有几个fn()被解析几次。

函数执行的时候,先进行形参赋值,再进行预解析可得知,在写代码时:

1.不要在一个函数内部定义一个和该函数的形参重名的函数
2.全局变量的定义尽量不要写在函数内部
3.让一个变量跨函数使用
    => 可以把多个函数内部使用的变量定义在几个函数的外面,在函数内部只是进行操作

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值