⌚️⌚️⌚️个人格言:时间是亳不留情的,它真使人在自己制造的镜子里照见自己的真相! 📖Git专栏:📑Git篇🔥🔥🔥 📖JavaScript专栏:📑js实用技巧篇,该专栏持续更新中🔥🔥🔥,目的是给大家分享一些常用实用技巧,同时巩固自己的基础,共同进步,欢迎前来交流👀👀👀 👉👉👉你的一键三连是对我的最大支持💙 💜 ❤️
本篇给大家带来js语法核心基础之预编译的讲解
var
和function
会进行声明提升示例:
broswer环境输出:
cpp语言中的i
未进行声明提升,即i
的作用域仅限for
循环当中
global
、window
、document
的区别此处我们介绍这三个对象是为后文的预编译做铺垫,概念比较容易区分,明白差异即可
global
:node环境中提供的全局对象window
:broswer环境中提供的全局对象document
:是window对象的一个属性,即显示于窗口内的一个文档,可理解为你的网页broswer环境输出:
demo();
function demo() {
var a = b = 1;
console.log(a,b);
}
console.log(demo);
browser环境输出:
函数dmeo
为经声明就可正常调用,执行函数demo
时,先将1赋值给b,再将b的值赋值给a;虽然a、b是在函数作用域中,但由于b未经声明,所以下面在browser环境中输出的结果表明b
在 window
属性中,而 a
则不会出现在全局对象中;函数demo
的声明是在全局作用域,所以它归window
对象所有
预编译步骤:
function fn(a) {
console.log(a);
var a = 333;
console.log(a);
function a() {}
console.log(a);
var b = function () {};
console.log(b);
console.log(c);
function c() {}
}
fn(1);
注意:预编译发生在函数执行之前,创建好了 AO 对象
下面分别对应“四部曲”的每一步:
📌注意:
动图解析预编译的作用结果(仔细观察每一步变化,帮助理解;另外提供一种思路:断点调试(此处不再演示)):
示例:
a = 100;
console.log(demo);
function demo(e) {
function e() {}
arguments[0] = 2;
console.log(e);
console.log(c);
if (!a) {
var b = 333;
function c() {}
}
var c;
a = 10;
var a;
console.log(b);
f = 222;
console.log(c);
console.log(a);
}
var a;
demo(1);
console.log(a);
console.log(f);
GO对象创建:
AO对象创建:
📌注意:if()
中嵌套的 function()
会被在预编译时创建AO对象过程中忽略,观察两次c的输出
前面以及提及过全局对象概念,下面再简述下全局对象的几个特点:
示例:
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script src="./js/1.js"></script>
<script src="./js/2.js"></script>
</body>
</html>
//1.js
var uncover = (function () {
var a = 1; // 避免污染
var b = 2; // 避免污染
// 暴露为:sayHi
function hello() {
console.log("hello world");
}
// 暴露为:count
var count = 1;
// 暴露为:array
var array = [666,'222','herm',undefined];
return {
sayHi: hello,
count: count,
array: array,
};
})();
//2.js
(function () {
var a = 3; // 避免污染
var b = 4; // 避免污染
// 使用 1.js文件 暴露的函数和变量
uncover.sayHi();
console.log(uncover.array);
console.log(uncover.count);
})();
当然,随着ES6的推出,以及词法作用域、模块化开发等知识的加入,此类问题很少再遇到
js预编译的知识是其语言的特性,同时也是初学者必须掌握的知识点之一