JavaScript是运行在浏览器上的脚本语言。我们平时看到丰富多彩的网页,这要在很大程度上归功于JavaScript。
引子 学点儿历史
JavaScript在编程语言的阵营里也是老资格了。它诞生于1995年,由Netscape公司的Brendan Eich,在网景导航者浏览器上首次设计实现而成。由于Netscape与Sun合作,Netscape管理层希望它外观看起来像Java,因此取名为JavaScript。
要知道,Java语言自其前身Oak语言在1992年诞生后,1995年才正式更名为Java,1996年1月,Sun公司才正式发布Java的第一个版本(JDK1.0)。
可见,就诞生时间而言,JavaScript可谓不折不扣的老资格编程语言。
实际上,Netscape最初将其脚本语言命名为LiveScript,后来Netscape在与Sun合作之后将其改名为JavaScript。
实际上,JavaScript最初受Java启发而开始设计,目的之一就是“看上去像Java”,因此语法上也有类似之处,甚至一些名称和命名规范也借自Java。但JavaScript的主要设计原则源自Self和Scheme。
在发展初期,JavaScript的标准并未确定,同期有Netscape的JavaScript,微软的JScript和CEnvi的ScriptEase三足鼎立。
1997年,在ECMA(欧洲计算机制造商协会)的协调下,由Netscape、Sun、微软、Borland组成的工作组确定统一标准:ECMA-262。
后来,Ecma国际以JavaScript为基础制定了ECMAScript标准。
Ecma国际的前身为欧洲计算机制造商协会,英文名称是European Computer Manufacturers Association,是一家国际性会员制度的信息和电信标准组织。在1994年之前,ECMA名为欧洲计算机制造商协会,后来由于计算机的国际化,该组织的标准也牵涉到很多其他国家,因此该组织决定改名表明其国际性,也就是现名称ECMA国际(Ecma International)。
可以说,ECMAScript是一种由Ecma国际通过ECMA-262标准化的脚本程序设计语言。这种语言在万维网上应用广泛,它往往被称为JavaScript或JScript,所以ECMAScript可以理解为是JavaScript的一个标准。实际上,JavaScript和JScript是ECMA-262标准的实现和扩展。
现在,完整的JavaScript包含三个部分:ECMAScript,文档对象模型DOM,浏览器对象模型BOM。
到此,历史回顾结束。
总的来说,JavaScript由三个部分构成。
其中,ECMAScript规定了JavaScript的语法;BOM规定了JavaScript访问浏览器的标准,是JavaScript操作浏览器的接口;浏览器会加载文档,我们在浏览器中看到的网页,就是浏览器加载的文档,DOM则规定了JavaScript操作网页文档的标准,是JavaScript操作网页文档的接口。
进入正题
JavaScript(简称“JS”)是一种弱类型的脚本语言。
与强类型语言Java不同,JS中声明变量时,不需要显式声明变量的类型。JS中声明的变量会根据语法环境的需要进行相应的隐式类型转换。
JavaScript的数据类型主要分为两大类,一类是基本类型,另一类是引用类型。
JavaScript中的基本类型包括4种,即string字符串,number数字,boolean布尔值,undefined。其中,undefined为变量声明后未赋值的情形。
引用类型又称为对象类型,对象分为普通对象(有时简称“对象”)和函数对象(有时简称“函数”)。普通对象属于Object类型,函数对象属于Function类型。同时,Function对象也都属于Object类型。
在上述图示中,分别列举了一个普通对象Object,以及一个函数对象Function。同时,Object和Function互为实例。
JavaScript中也存在一种特殊的继承关系,这种继承关系表现在一个赋值表达式的两侧中,左侧“继承"了右侧的数据结构,可以动态扩展右侧对象的数据结构。
另外,函数对象存在原型,普通对象则无原型属性。
函数对象可以通过原型prototype扩展其数据结构,也可以直接通过实例.属性扩展数据结构;函数对象的实例可以通过__proto__扩展其数据结构。
由于JavaScript可以在运行中动态改变数据结构,所以JavaScript也可以称为动态类型语言。
总的来说,在JavaScript中,对象是键值对的组合。
原型是JavaScript的一大特点。
此外,JavaScript还有一个重要的概念,那就是闭包。
闭包听起来比较抽象,那么何为闭包呢?
对此,官方给出的解使是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
通常来说,当在一个函数内部再声明函数时,内部函数可以访问其所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。从某种程度上来说,闭包也是JavaScript语言的一种内在的,保留对词法环境下的资源进行访问的机制。
在JavaScript中,可以说,一切皆为对象,即便是基本类型的变量,也可以通过隐式创建对应包装类型的临时对象来作为对象使用。
在图中,外部函数中声明的局部变量,可以被其内部声明的其他内部函数使用。这之中就是闭包在起作用。从这个角度来看,闭包也是一种特殊的机制,可以使得内部函数保留其对词法环境中资源的访问。
应该说,学习JavaScript,能够对原型与闭包有个清晰的认识,堪称学习到了JavaScript的精髓。
另外,JavaScript中的作用域主要分为全局作用域和局部作用域,由此引申出全局变量和局部变量。
比如说,一个JavaScript脚本运行在一个浏览器窗口中,这个浏览器窗口对应一个window对象,JavaScript脚本中作用域在整个浏览器窗口之内的变量,就称为全局变量;那些仅局限在一个代码块或一个函数内的作用域的变量则称为局部变量。
在一个函数内部,若以var声明一个变量,那么这个变量就是一个局部变量;如果在函数内部直接声明一个变量,未添加var关键字,这个变量就是全局变量。
未在任一函数内部声明的变量,无论是否有var关键字修饰,均是全局变量。
谈谈BOM
JavaScript是一门灵活的脚本语言,其主要应用在于对浏览器,及浏览器加载的网页的操作。JavaScript是通过BOM操作浏览器的。
BOM的全拼是Browser Object Module,译为浏览器对象模型。BOM的*对象是window,表示一个打开的浏览器窗口。
上图中,document,location,navigation,history等既是window对象的属性,又是对象,因此又称为window对象的子对象。
window对象在JavaScript中作为全局Global对象,在调用全局对象的属性和方法时,全局对象可以省略。
比如,我们平时见到的类似alert(),console()等方法可以直接调用,这些方法就是window对象的方法。对于window对象的这些方法,我们可以通过window对象名来调用,也可以省略window对象名进行直接调用。
我们平时在JavaScript脚本中定义的全局变量,均可以作为window对象的属性。
另外,window对象的属性和方法可以动态扩展。
直接声明全局变量作为window对象的属性,以及声明window对象的属性作为全局变量,两者有一些区别。比如,直接声明的全局变量不能通过delete删除,而声明的window对象的属性可以通过delete删除。
总的来说,BOM中最重要的对象非window对象莫属。window对象不仅是BOM定义的*对象,还是JavaScript中的全局对象。不过,BOM目前没有统一的标准,各浏览器厂商(如Chrome,Opera,Firefox,Safari等)各自对BOM有着不同的实现。在web前端开发中,通常需要做浏览器兼容,根源就在于各浏览器厂商的BOM模型不统一造成的。
另外,BOM模型中的window对象有个属性document,这个属性还是一个对象,它是DOM的*对象。
聊聊DOM
DOM的全拼是Document Object Module,译为文档对象模型。我们平时用JavaScript脚本操作网页中的元素,就是通过DOM来操作的。可以说,DOM是JavaScript脚本操作网页元素的接口。
DOM的标准是统一的,其标准制定者是W3C。因此,DOM不需要做浏览器兼容,在浏览器平台上的标准是统一的。
DOM的*对象是document,这是BOM中定义的window对象的一个子对象。DOM从结构上看,是一颗“树”:
我们平时打开浏览器并访问网页,顺序是这样的:浏览器通过各自的BOM通过DOM加载网页文档,当网页文档在浏览器中被加载完毕时,JavaScript可以通过获取网页元素来操作这些元素,从而实现特定的效果。
应该说,JavaScript语言入门并不太难,难在懂得其内在运行原理。同时,由于JavaScript广泛的用途,以及简化的需要,也产生了不少JavaScript框架,比较著名的有jQuery,easyUI等。要深入掌握这些JavaScript框架,就离不开洞悉JavaScript的运行原理。
到此,相信您对JavaScript已经有了一个清晰的了解,接下来的工作,请结合实际应用,进行足够的有效练习,相信您一定能够玩转JavaScript!