JavaScript之预编译与变量提升windowAOGOreturnif

Posted web半晨

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript之预编译与变量提升windowAOGOreturnif相关的知识,希望对你有一定的参考价值。

目录


1、概述

JavaScript代码在执行之前首先经过预编译。预编译的过程中函数声明会被整体提升,变量只有声明被提升,赋值留在原地。


2、示例代码-1-函数的提升

precompileVariablePromotion();
function precompileVariablePromotion() 
	console.log('预编译/变量提升');

precompileVariablePromotion();

此例中的两种执行顺序都能正确调用函数,说明函数发生了提升,且函数体的内容也一同被提升。


3、示例代码-2-基本数据类型的提升

console.log(a);
// undefined
var a;
console.log(a);
// undefined

a = 7;
console.log(a);
// 7

此例中的a在打印时都没有报错,所以说明了a被提升了,只是没有赋值,所以前两个打印的值为undefined,第三个打印才是赋值,也说明了赋值留在原地。


4、示例代码-3-函数提升优先级高于基本类型数据的提升

console.log(precompileVariablePromotion);
// ƒ precompileVariablePromotion(precompileVariablePromotion) 
//     var precompileVariablePromotion = 7;
//     var precompileVariablePromotion = function ()  ;
// 
var precompileVariablePromotion = 3;
function precompileVariablePromotion(precompileVariablePromotion) 
	var precompileVariablePromotion = 7;
	var precompileVariablePromotion = function ()  ;

var precompileVariablePromotion = 3;

此例中函数发生了提升,并且函数体同时被提升。因为函数提升的优先级高于基本类型数据提升,所以函数提升会覆盖掉所有同名的基本类型数据提升。


5、window对象

var a = 1;
b = 2;
console.log(window.a, window.b);
// 1 2

window.a = 7;
window.b = 6;

console.log(window.a, window.b);
// 7 6

此例中的两种方式是一样的效果,都是把值挂载到window对象上。


6、在一个函数中给一个未定义的变量赋值,变量会被挂载到window对象上

function precompileVariablePromotion() 
	var a = b = 7;
	// 在一个函数中给一个未定义的变量赋值,
	// 此变量会被挂载到window对象上

precompileVariablePromotion();
// console.log(a);
// Uncaught ReferenceError: a is not defined
console.log(window.b, b);
// 7 7
// 此处的b被挂载到window上了

7、函数内的变量提升

function precompileVariablePromotion(params) 
	console.log(params);
	// 因为函数提升的优先级最高,
	// 所以此处打印的是函数表达式
	// ƒ params()  
	var params = 7;
	console.log(params);
	// 因为到此处时之前的变量提升已经结束,
	// 已经到了赋值阶段
	// 所以打印了7
	// 7
	function params()  ;
	// 当代码运行到此处时,
	// 函数已经提升过了
	// 所以不会再做任何操作
	// 因此下一个打印的值依然是7
	console.log(params);
	// 7
	var b = function ()  ;
	console.log(b);
	// ƒ ()  
	function c()  ;

precompileVariablePromotion(3);

8、函数形参的提升优先级低于函数

function precompileVariablePromotion(a, b) 
	console.log(a);
	// 3
	c = 7;
	var c;
	a = 5;
	b = 6;
	console.log(b);
	// 6

	function b()  ;
	// 在预编译时b已经被提升,
	// 所以在运行时不会再做任何操作
	// 也就是说 b = 6; 能正常赋值
	// 所以两个打印都是 6

	function d()  ;
	console.log(b);
	// 6

	// 如果打开此处的注释
	// 那么第一打印就是
	// 这里进步一步说明了
	// 函数提升的优先级高于形参提升的优先级
	// ƒ a()  
	// function a()  ;

precompileVariablePromotion(3);

9、GO(global object)全局上下文

console.log(precompileVariablePromotion);
// ƒ precompileVariablePromotion() 
//    console.log(7);
// 
var precompileVariablePromotion = 1;
function precompileVariablePromotion() 
	console.log(7);

console.log(precompileVariablePromotion);
// 1
// 在预编译时,函数声明已被提升
// 之后声明了变量,且给变量赋值为1
// 所以在函数后面打印到的就是1

10、只有函数声明才会发生函数体一同提升

console.log(a);
// ƒ a()  
console.log(b);
// undefined
// 因为b就是个普通的变量
// 在此处b发生了变量提升
// 但是没有值
// 所以是undefined
// 只有函数声明才会发生变量提升和函数体一起提升
function a()  ;
var b = function ()  ;

11、往外查找变量

function precompileVariablePromotion() 
	var a = b = 7;
	// 此处的b被挂载到全局window上
	console.log(a);
	// 7
	console.log(b);
	// 7
	console.log(window.b);
	// 7

precompileVariablePromotion();
// console.log(a);
// Uncaught ReferenceError: a is not defined
console.log(b);
// 7

12、如果自己身上有就不往外查找

var b = 2;
function precompileVariablePromotion() 
	var a = 3,
		b = 7;
	console.log(a);
	// 3
	console.log(b);
	// 7
	// 因为函数内部有b变量,
	// 所以不会往外查找
	console.log(window.b);
	// 2

precompileVariablePromotion();
console.log(b);
// 2

13、AO与GO结合、并且注意函数是否被调用

var b = 3;
console.log(a);
// ƒ a(a) 
//     console.log(a);
//     var a = 2;
//     console.log(a);
//     function a() 
//         var b = 5;
//         console.log(b);
//     
// 
function a(a) 
	console.log(a);
	// ƒ a() 
	//     var b = 5;
	//     console.log(b);
	// 
	var a = 2;
	console.log(a);
	// 2
	function a() 
		var b = 5;
		console.log(b);
	

a(1);

14、是否往全局查找变量

a = 1;
function test() 
	console.log(a);
	// undefined
	// 函数内发生了变量提升
	// 因为 var a = 3;
	// 所以不会往全局找
	a = 2;
	console.log(a);
	// 2
	var a = 3;
	console.log(a);
	// 3


test();
var a;

15、预编译只管找变量和形参,不关注代码是否会被执行,所以变量提升与执行时是否进入某个判断无关

function test() 
	console.log(b);
	// undefined
	// 预编译只管找变量和形参,
	// 不关注代码是否会被执行
	// 所以变量提升与是否进入某个判断无关

	console.log(a);
	// undefined
	// 此处的a用的是GO(全局)里面的变量
	if(a)
		var b = 2;
	
	c = 3;
	console.log(c);
	// 3

var a;
test();
a = 1;
console.log(a);
// 1

16、函数内变量提升并返回(return在后)

function test() 
	a = 1;
	function a()  ;
	var a = 2;
	return a;

console.log(test());
// 2

17、函数内变量提升并返回(return在前)

function test() 
	return a;
	a = 1;
	function a()  ;
	var a = 2;

console.log(test());
// ƒ a()  

18、变量提升不会阻碍判断

a = 1;
function test(e) 
	function e()  ;
	arguments[0] = 2;
	console.log(e);
	// 2
	console.log(a);
	// a发生了变量提升
	// 但是还没有赋值
	// 所以进不了判断
	if (a) 
		var b = 3;
	
	var c;
	a = 4;
	var a;
	console.log(b);
	// undefined
	// b发生了变量提升
	// 因为预编译不管是否会进入判断
	// 都会发生变量提升
	f = 5;
	console.log(c);
	// undefined
	console.log(a);
	// 4

var a;
test(1);

以上是关于JavaScript之预编译与变量提升windowAOGOreturnif的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript之预编译

JavaScript之预编译学习(附带多个面试题)

JavaScript之预编译学习(附带多个面试题)

JavaScript之预编译学习(内含多个面试题) #yyds干货盘点#

js之预解析

JS之预编译和执行顺序(全局和函数)