JavaScript学习笔记(三):JavaScript也有入口Main函数


Posted in Javascript onSeptember 12, 2015

在C和Java中,都有一个程序的入口函数或方法,即main函数或main方法。而在JavaScript中,程序是从JS源文件的头部开始运行的。但是某种意义上,我们仍然可以虚构出一个main函数来作为程序的起点,这样一来不仅可以跟其他语言统一了,而且说不定你会对JS有更深的理解。

1. 实际的入口

当把一个JavaScript文件交给JS引擎执行时,JS引擎就是从上到下逐条执行每条语句的,直到执行完所有代码。

2. 作用域链、全局作用域和全局对象

我们知道,JS中的每个函数在执行时都会产生一个新的作用域。具体来说,在执行流程进入函数时会建立一个新的作用域,在函数执行完成退出时会销毁这个作用域。函数的形参、局部变量都会绑定到这个作用域里,当函数调用完成作用域销毁时,它们随之被销毁。当然在特殊情况下,如果函数返回时作用域中的某些变量仍然被引用,那么作用域以及这些被引用的变量就不会被销毁,从而形成所谓的闭包。

另一方面,我们知道函数是可以嵌套的,因而作用域也是可以嵌套的。函数在定义的时候,JS引擎会给每个函数设置一个称为[[scope]]内置属性,它指向外部函数的词法作用域。通过这种方式,多个作用域形成了链式结构,称为作用域链。通常情况下,在任意时刻只存在一条作用域链,即从正在执行的函数的作用域开始,层层上溯,直到最外层的全局作用域。

[注]:作用域链上的函数就是JS源码里的层层嵌套的函数,跟函数执行时的顺序或函数调用栈无关,这也是词法作用域这个称呼的由来。

全局作用域是一个特殊的作用域,它不是一个函数作用域,但它是所有函数作用域的外层作用域,也是所有作用域链的终点。因此只要程序没有退出,全局作用域总是存在的,全局作用域内的变量也是一直有效的。

[函数3的作用域]-->[函数2的作用域]-->[函数3的作用域]-->[全局作用域]

另外,对应于全局作用域,还有一个全局对象。在浏览器中,全局对象就是window对象。全局对象是个特殊的对象:

在全局作用域中定义的变量,都会绑定到全局对象。

在任意作用域中定义的变量,如果定义时没有用 var 关键字,都会绑定到全局对象。

在全局作用域中, this 指向全局对象。

从上面列举的这些特性可以看出,如果把全局作用域当成一个对象的话,那么实际上它就是全局对象。另外,这也解释了在全局作用域中,下面的四条语句为什么是等价的:

var a = 1;
a = 1;
window.a = 1;
this.a = 1;

3. 虚构的main函数

既然都是作用域,为什么要有一个特殊的全局作用域呢?我们总是喜欢简单化、一致性,而尽量避免复杂化、特殊性。所以很自然地,我们会想能否让全局作用域看起来跟函数作用域没什么区别?答案是肯定的。我们可以做这样的构想:

 我们想象,在JS引擎执行源文件时,会将文件中的代码包装到一个叫做main的函数中。然后把这个main函数作为程序的入口。
也就是说,假设一个JS文件中有这样的代码:

var a = 1;
var b = 2;

function add(x, y) {
  var z = x + y;
  return z;
}
console.log(add(a, b));

JS引擎在程序开始执行前会把它包装成一个main函数:

// 虚构的main函数
function main() {
  var a = 1;
  var b = 2;

  function add(x, y) {
    var z = x + y;
    return z;
  }

  console.log(add(a, b));
}

然后,调用这个main函数:

main._current_scope_ = window; // 将全局作用域(对象)设为window
main.call(window) // 将this指向window

4. 意义何在?

(1) JS也有了入口函数main,跟其他语言一致了。

(2) 省去了全局作用域的概念,或者说全局作用域也成了函数作用域。

(3) 通过上面对main函数的调用过程,可以明白全局作用域中的那些特殊性质的由来。

(4) 最后一点,将所有JS源码当成一个函数,是为了后面讲事件队列、事件循环做铺垫。

以上就是小编给大家介绍的JavaScript学习笔记(三):JavaScript也有入口Main函数,希望大家喜欢。

Javascript 相关文章推荐
Hutia 的 JS 代码集
Oct 24 Javascript
IE 下的只读 innerHTML
Aug 21 Javascript
document.getElementById介绍
Sep 13 Javascript
100个不能错过的实用JS自定义函数
Mar 05 Javascript
JavaScript实现三阶幻方算法谜题解答
Dec 29 Javascript
JS动画效果打开、关闭层的实现方法
May 09 Javascript
基于Vue.js的表格分页组件
May 22 Javascript
vue的基本用法与常见指令
Aug 15 Javascript
layui 给数据表格加序号的方法
Aug 20 Javascript
vue.js 实现点击按钮动态添加li的方法
Sep 07 Javascript
layer更改皮肤的实现方法
Sep 11 Javascript
使用vue制作滑动标签
Sep 21 Javascript
JS实现仿QQ面板的手风琴效果折叠菜单代码
Sep 11 #Javascript
JS实现仿Windows7风格的网页右键菜单效果代码
Sep 11 #Javascript
jQuery+css实现的蓝色水平二级导航菜单效果代码
Sep 11 #Javascript
js实现的后台左侧管理菜单代码
Sep 11 #Javascript
微信企业号开发之微信考勤Cookies的使用
Sep 11 #Javascript
微信企业号开发之微信考勤百度地图定位
Sep 11 #Javascript
JavaScript处理解析JSON数据过程详解
Sep 11 #Javascript
You might like
当年上海收录机产品生产,进口和价格情况
2021/03/04 无线电
基于PHP选项与信息函数的使用详解
2013/05/10 PHP
php 强制下载文件实现代码
2013/10/28 PHP
取得单条网站评论以数组形式进行输出
2014/07/28 PHP
thinkPHP5框架分页样式类完整示例
2018/09/01 PHP
jquery 模拟雅虎首页的点击对话框效果
2010/04/11 Javascript
原生Javascript封装的一个AJAX函数分享
2014/10/11 Javascript
jquery中post方法用法实例
2014/10/21 Javascript
jQuery实现Div拖动+键盘控制综合效果的方法
2015/03/10 Javascript
每天一篇javascript学习小结(Date对象)
2015/11/13 Javascript
JavaScript基础之AJAX简单的小demo
2017/01/29 Javascript
vsCode安装使用教程和插件安装方法
2020/08/24 Javascript
解决Vue打包后访问图片/图标不显示的问题
2019/07/25 Javascript
Vue2.0 实现页面缓存和不缓存的方式
2019/11/12 Javascript
[51:34]Ti4主赛事胜者组 DK vs EG 2
2014/07/19 DOTA
opencv改变imshow窗口大小,窗口位置的方法
2018/04/02 Python
利用python脚本如何简化jar操作命令
2019/02/24 Python
PyQt5图形界面播放音乐的实例
2019/06/17 Python
python实现猜数字游戏
2020/03/25 Python
python实现文件批量编码转换及注意事项
2019/10/14 Python
Python3 使用selenium插件爬取苏宁商家联系电话
2019/12/23 Python
Python Matplotlib绘图基础知识代码解析
2020/08/31 Python
HTML5网页音乐播放器的示例代码
2017/11/09 HTML / CSS
AmazeUI 评论列表的实现示例
2020/08/13 HTML / CSS
秦兵马俑教学反思
2014/02/07 职场文书
给老婆大人的检讨书
2014/02/24 职场文书
市场营销调查计划书
2014/05/02 职场文书
需求分析说明书
2014/05/09 职场文书
党支部综合考察材料
2014/05/19 职场文书
承诺书范本
2015/01/21 职场文书
部门优秀员工推荐信
2015/03/24 职场文书
涨价通知怎么写
2015/04/23 职场文书
2015年车间安全管理工作总结
2015/05/13 职场文书
初中同学会致辞
2015/08/01 职场文书
2016中秋节问候语
2015/11/11 职场文书
MongoDB日志切割的三种方式总结
2021/09/15 MongoDB