JavaScript预解析

JavaScript预解析


预解析

一、什么是预解析
  • 预:在所有js代码执行前

  • 解析:对整篇js代码进行通读并解释(浏览器在解析)

二、解析了什么内容
  • var 声明的变量

    • var  num
      
  • 声明式函数(不是赋值式函数)

    • function  fn( )  { }
      
三、怎么解析的
  • var 声明的变量
    • 在所有 js 代码执行前,先把变量声明好
    • 再开始执行代码
  • 案例1
	/*
		var num = 100
      	这一行代码包含了两个操作
        	1. 声明变量 var num
        	2. 变量赋值 num = 100
     	在这两个操作里面
        	声明变量那一步是在预解析的时候就完成的,在所有js代码开始执行之前, 就已经做好了
        	变量赋值那一步是在真正执行代码的时候才开始做的
	*/
	
	var num = 100
  • 案例2
      /*
    	拆解代码的执行过程
    	1、预解析的过程:在所有 js 代码执行前,先把变量声明好
    		var num
    	2、真正执行所有的js代码
            console.log(num) // 其实就是有这个变量,但是还没有赋值,就是undefined
    		num = 100
    */
    
    console.log(num) // undefined
    var num = 100
  • 声明式函数
    • 在所有 js 代码执行前,先把函数名声明好,并且给这个函数赋值为一个函数
    • 再开始执行代码
  • 案例1
    /*
      function fn() {}
      解析一下这一行代码

      1. 预解析的过程
        告诉浏览器, fn 是一个可以使用的名字
        并且 fn 这个名字是一个函数

      2. 真正的代码开始执行
    */
    
    function fn() {}
  • 案例2
    /*
      1. 预解析
        告诉浏览器 fn 这个名字被声明过了,可以使用
        并且 fn 还是一个函数 function fn() { console.log('我是 fn 函数') }
      2. 真正的开始执行所有js代码
        fn()
    */
    
    fn()
    function fn() {
      console.log('我是 fn 函数') // 我是 fn 函数
    }

赋值式函数的预解析

  • 赋值式函数不会按照声明式函数的预解析规则进行

  • 而是按照 var 的预解析规则进行

  • var fn = function ( ) { }
	/*
      分析代码执行过程
      fn()
      var fn = function () {}

      1. 进行预解析
        var fn
        就告诉浏览器这个 fn 被声名过了, 但是并没有给他赋值为一个函数
      2. 代码开始执行
        fn() // 这行代码执行的时候, fn 还是一个没被赋值的状态, 是个 undefined
        fn = function () {}

      所以赋值式函数只能后调用
    */
    
    fn() // 控制台报错:fn is not a function
    var fn = function () {
      console.log('我是 fn 函数')
    }

预解析的无节操

  • 不管 if 条件是不是成立,写在里面的代码都会进行预解析
  • 只是条件不成立的时候,不会执行 { } 里面的赋值操作
	console.log(age) // undefined
    if (2 > 1) {
      var age = 18
    }
    console.log(age) // 18
    
    /*
    	分析代码执行过程
    	1. 先进行预解析
        	var age
        	告诉浏览器, age 这个变量被声名过, 可以使用
      	2. 开始真正的代码执行
        	console.log(age) // age 还没有被进行赋值, 就是 undefined
        	if (2 > 1) {
          		age = 18
        	}
        	console.log(age) // age 已经被赋值过了, 就是 18
    */
	console.log(age) // undefined
    if (2 < 1) {
      var age = 18
    }
    console.log(age) // undefined
    
    /*
      解析代码执行过程
      1. 预解析 - 不管 if 是否成立
        var age
      2. 代码执行
        console.log(age) // 没有进行赋值, 就是 undefined
        if (2 < 1) {
          age = 18
        }
        console.log(age) // 因为 if 条件为 false, 所以 {} 里面的代码没有执行,就是 undefined
    */
  • 当在函数内部的时候, return 后面的代码虽然不会执行
  • 但是会进行预解析
	function fn() {
      console.log(num) // undefined

      return
      var num = 100
    }
    fn()
  • 预解析小案列
	var a = b
    a = 10
    b = 20
    console.log(a)
    console.log(b)
    
    /*
      代码执行过程     
      1. 预解析
        var a
        告诉浏览器 a 是一个可以使用的变量
      2. 代码执行
        a = b // 使用 b 这个变量给 a 进行赋值, 但是 b 变量并没有被声名过, 报错:b is not defined
        a = 10
        b = 20
        console.log(a)
        console.log(b)
    */

预解析的优先级

  • 当你定义一个变量和一个声明式函数的时候
  • 如果变量名和函数名充满,在进行预解析的时候,以函数为准
	console.log(num) // ƒ num() { console.log('我是一个函数') }
    var num = 100
    console.log(num) // 100
    function num() {
      console.log('我是一个函数')
    }
    console.log(num) // 100
    
    /*
      1. 预解析
        告诉浏览器 num 这个变量可以使用
        告诉浏览器 num 这个变量可以使用, 并且赋值为一个函数
        当预解析结束的时候
        num 就是一个函数
      2. 真正的代码开始执行
        console.log(num) // 此时因为刚刚预解析结束, 所以 num 就是一个函数
        num = 100        // 给 num 重新赋值, 赋值为 100, 那么就不在是一个函数了
        console.log(num) // 因为已经给 num 从新赋值完毕了,  打印出来 100
        console.log(num) // 因为已经给 num 从新赋值完毕了,  打印出来 100
    */
	console.log(num) // 打印 num 这个变量的值,即:num 就是一个函数 
    num(100) // 调用 num 函数, 传递一个 100 作为实参
    
    var num = 100
    console.log(num) // 100
    
    num(200) // 报错:num is not a function, 因为到这里 num 已经不是函数了, 是 100 这个数值
    function num(a) {
      console.log(a) // 打印 a 形参, 接收的是 num() 的时候传递进来的实参100
      console.log('我是一个函数')
      // console.log(a)
    }
    console.log(num)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值