zoukankan      html  css  js  c++  java
  • 变量名提升

    变量名提升

    	var num = 123;
    	function foo1 () {
    		console.log( num );
    		var num = 456;
    		console.log( num );
    	}
    	foo1();
    
    1. 预解析的过程
    2. 代码的执行过程

    程序在执行过程, 会先将代码读取到内存中检查. 会将所有的声明在此时进行标记. 所谓的标记就是
    让 js 解释器知道有这个名字, 后面在使用名字的时候, 不会出现未定义的错误. 这个标记过程就是提升.

    声明:

    1. 名字的声明, 标识符的声明( 变量名声明 )
      • 名字的声明就是让我们的解释器知道有这个名字
      • 名字没有任何数据与之对应
    2. 函数的声明
      • 函数声明包含两部分
      • 函数声明与函数表达式有区别, 函数声明是单独写在一个结构中, 不存在任何语句, 逻辑判断等结构中
    	function f() {
    		function func() {
    		} // 声明
    	
    		if ( true ) {
    			function func2() {} // 函数表达式
    		}
    		var f = function func3 () {}; // 函数表达式
    		
    		this.sayHello = function () {}; // 函数表达式
    		
    		
    		var i = 1;
    		function func4 () {}  // 函数声明
    		var j = 2;
    	}
    
    * 首先函数声明告诉解释器有这个名字存在. 该阶段与名字声明一样
    * 告诉解释器, 这个名字对应的函数体是什么
    
    	var num = 1;
    	function num () {
    		alert( num );
    	}
    	num();
    

    分析:

    1. 预解析代码, 提升名字
      • 首先提升名字 num
      • 再提升函数名, 但是名字已经存在 因此只做第二部, 让名字与函数体对应上
      • 结论就是 代码中已经有一个 函数 num 了
    2. 开始执行代码, 第一话从 赋值语句开始执行
      • 给 num 赋值为 1
      • 覆盖了函数
    3. 调用 num, 由于 num 中存储是 数字 1, 因此报错

    练习:

    	var num = 123;
    	function foo1 () {
    		console.log( num );
    		var num = 456;
    		console.log( num );
    	}
    	foo1();
    
    1. 预解析, 提升 num 名字和 foo1 函数
    2. 执行第一句话: num = 123;
    3. 执行函数调用
      • 函数调用进入函数的一瞬间也需要预解析. 解析的是变量名 num
      • 在函数内部是一个独立的空间, 允许使用外部的数据. 但是现在 num 声明同名, 即覆盖外面的
      • 执行第一句 打印 num, 没有数据 undefiend
      • 执行第二句 赋值: num = 456
      • 执行第三局 打印 num, 结果 456

    练习

    	if ( ! 'a' in window ) {
    		var a = 123;
    	}
    	console.log( a );
    
    1. 预解析, 读取提升 a, 有一个名字 a 存在了
    2. in 运算符: 判断某一个字符串描述的属性名是否在 对象中
      • var o = { name: 'jim' }; 'name' in o , 'age' in o
      • 执行第一个判断: ! 'a' in window
        • 'a' in window 真
        • ! 得到 假
      • if 内部的赋值不进行
    3. 打印结果 a 的值为 undefined

    代码:

    	if ( true ) {
    		function f1 () {
    			console.log( 'true' );
    		}
    	} else {
    		function f1 () {
    			console.log( 'false' );
    		}
    	}
    	f1();
    
    1. 预解析: 提升 f1 函数, 只保留最后提升的内容, 所以打印是 false
    2. 执行代码, 第一句话就是有一个 空的 if 结构
    	if ( true ) {
    		
    	} else {
    		
    	}
    
    1. 执行函数调用, 得到 false

    问题:
    function foo() {}
    var foo = function () {};

    1. 上面的语法是声明, 可以提升, 因此在函数定义的上方也可以调用
    2. 下面的语法是函数表达式, 函数名就是 foo, 它会提升. 提升的不是函数体
    3. 函数表达式也是支持名字语法的
    	var foo = function func () {
    	};
    	
    	func();
    
    * 函数有一个属性 name, 表示的是函数名. 只有带有名字的函数定义, 才会有 name 属性值, 否则是 ""
    * 但是, 函数表达式的名字, 只允许在函数内部使用. IE8 可以访问
    * () 可以将数据转换为表达式
    

    新的浏览器中, 写在 if, while, do-while 结构中的函数, 都会将函数的声明转换成 特殊的函数表达式
    将代码

    	if (...) {
    		function foo () { ... }
    	}
    

    转换成

    	if (...) {
    		var foo = function foo () { ... }
    	}
    
  • 相关阅读:
    DPDK — 网卡初始化流程(Intel 82599 ixgbe 网卡驱动示例)
    leetcode 3. 无重复字符的最长子串
    20193120 实验四 Python综合实践
    hadoop常用的端口号
    Django学习笔记
    ORACLE EBS AP invoice 到付款的数据流
    EBS 系统标准职责定义MAP
    Advanced Pricing
    Oracle Advanced Pricing White Papers
    增加AP INVOICE 行&分配行
  • 原文地址:https://www.cnblogs.com/jiaozhuo/p/5743089.html
Copyright © 2011-2022 走看看