1.核心JavaScript笔记:简介、基本语法

本系列内容由ZouStrong整理收录

整理自《JavaScript权威指南(第六版)》,《JavaScript高级程序设计(第三版)》

JavaScript是面向Web的编程语言,所有的浏览器都包含了JavaScript解释器

JavaScript是一门动态的、弱类型的、面向对象的、解释型语言,非常适合面向对象和函数式的编程风格

一. JavaScript简介

  • 时间:1995年
  • 人物:Brendan Eich(布兰登•艾奇)
  • 背景:Web早期时候,为了完成简单的表单验证,必须把表单数据发送到服务器端才能确定用户是否填写某个必填域、是否输入了无效的值…..这种频繁地与服务器交换数据只会加重用户的负担(当时的网速也是让人醉了)
  • 事件:Netscape(网景公司)希望通过JavaScript来解决这个问题,JavaScript作为Netscape浏览器的脚本语言问世(所以JavaScript出现的目的就是负责以前由服务器端语言处理的一些输入验证操作)

JavaScript的用途早已经不再局限于此,也超出了“脚本语言”本身的范畴,而是具备了与网页内容和浏览器窗口等几乎所有方面交互的能力,并且随着Node.js的普及,在非浏览器环境(服务端)的表现一样十分强大

小结

JavaScript原名LiveScript,Netscape为了搭上媒体热炒]ava的顺风车,才把LiveScript改名为JavaScript(所以Java和JavaScript的关系,就相当于雷锋和雷峰塔的关系)

二. JavaScript实现

随着JavaScript的普及,IE浏览器也加入了名为JScript的JavaScript实现,由于没有语言标准,导致了不同的语法和特性支持,因此JavaScript标准化被题上日程

1997年,欧洲计算机制造商协会( ECMA)定义了名为ECMAScript(ECMA-262)的脚本语言标准,它是通用的,与平台无关的语言标准

自此以后,浏览器开发商开始致力于将ECMAScript作为各自JavaScript实现的基础(基础虽然相同,但具体实现在不同浏览器上却略有不同)

一个完整的JavaScript实现包括以下三点

  • 核心(ECMAScript)
  • 文档对象模型(DOM)
  • 浏览器对象模型(BOM)

1. ECMAScript——提供语言核心功能

ECMAScript不针对任何特定浏览器,与浏览器没有依赖关系,并且本身并不包含输入和输出定义

ECMAScript定义的只是这门语言的基础,而在此基础之上可以构建更完善的脚本语言。Web浏览器只是ECMAScript实现的宿主环境之一(其他宿主环境包括Node.js和Flash等)

宿主环境不仅实现了基本的ECMAScript语法,也对其进行了扩展(新的API),而这些扩展——如DOM,则利用ECMAScript 的核心类型和语法提供更多更具体的功能

ECMAScript规定了这门语言的下列组成部分:

  1. 语法
  2. 数据类型
  3. 语句
  4. 关键字
  5. 保留字
  6. 运算符
  7. 对象

小结

  • ECMAScript是JavaScript的国际标准
  • JavaScript是ECMAScript的实现
  • ECMAScript最新版为第6版(Harmony),支持比较完善的是第5版,几乎完全支持的是第三版

2. DOM——提供访问和操作网页内容的方法和接口

文档对象模型( DOM, Document Object Model ) 是一个应用程序编程接口( API, Application Prograrmning lnterface),把整个页面映射为一个多层节点结构

借助DOM 提供的API ,可以轻松的删除、添加、替换或修改任何节点

DOM规范的最新版为——DOM 3级

3. BOM——提供与浏览器窗口交互的方法和接口

浏览器对象模型( BOM, Browser Object Model ) 是一个应用程序编程接口,把整个浏览器窗口映射为一个对象

借助BOM提供的API ,可以控制浏览器窗口的表现和行为

BOM最让人头疼的是没有相关的规范和标准,每个浏览器都有独有的实现(这个问题在HTML5 中得到了解决,HTML5把很多BOM功能规范化)

三. JavaScript价值

JavaScript对于页面的价值应该是"有了会更好"而不是"我离不开你",也就是说使用JavaScript应尽可能提高可访问性,而关闭JavaScript后,页面仍然都能正常访问

总的来说,使用JavaScript的好处有

  1. 增强用户体验
  2. 减少与服务器交互
  3. 对用户快速反馈
  4. 增强交互性
  5. 增强易用性
  6. ...

四. JavaScript引入

引入JavaScript使用<script>元素,它拥有6个可选的属性

type属性

<script type="text/javascript"></script>	

表示脚本类型,一般情况值都为"text/javascript",但是HTML5已经不推荐加入该属性,因为默认都是引入JavaScript脚本

src属性

<script src="js/script.js"></script>

表示要引入的外部JavaScript文件的URL

charset属性

表示通过src属性引入的脚本的字符编码(几乎不用)

language属性

已废弃,由type属性代替

async属性

表示异步脚本,页面解析到script时,该脚本会立即被下载,同时执行,但不妨碍页面其它元素的继续加载和解析

只对外部脚本文件有效

defer属性

表示延时脚本,页面解析到script时,该脚本立即下载,但延迟到文档完全被解析和显示之后再执行

只对外部脚本文件有效

小结

使用defer属性,可以让脚本在文档完全呈现之后再执行。延迟脚本总是按照指定它们的顺序执行

使用async属性,可以表示当前脚本不必等待其他脚本,也不必阻塞文档呈现(所以不要在异步脚本里处理DOM,除非脚本放在了页面底部)。但不能保证异步脚本按照它们在页面中出现的顺序执行

引入JavaScript有两种方式:

1. 嵌入式JavaScript

<script>
	//代码在这
</script>

包含在<script>元素内部的JavaScript 代码将被从上至下依次解释,并且在解释完毕之前,其后的内容都不会被加载

使用嵌入代码时,不要在代码中的任何地方出现"</script>" 字符串,因为会被浏览器解析为闭标签</script>(外部JS文件中可以出现)

可以通过转义和字符串拼接方法来解决该问题

alert("<\ /script>");
alert("</sc"+"ript>");

2. 外部JavaScript

<script src="example.js"></script>

与解析嵌入式JavaScript 代码一样,外部文件代码将被从上至下依次解析,在解析外部JavaScript 文件(包括下载该文件)时,页面的处理也会暂时停止

带有src属性的<script>标签之间的嵌入式JavaScript代码会被忽略

<script src="example.js">
	alert(1);  //永远不会执行
</script>	

通过<script>元素的src属性不仅可以引入与包含它的页面位于同一个服务器上的文件,还可以包含来自外部域的JavaScript文件(不受同源策略的限制,图片也是如此),这也是不安全的因素,谁也不知道第三方脚本是否包含恶意代码

无论如何包含代码,只要不存在defer和async属性,浏览器都会按照<script>元素在页面中出现的先后顺序对它们依次进行解析

外部JavaScript文件可维护、可缓存、适应未来,因此推荐使用

3. <script>元素的位置

一开始<script>元素都是位于<head>元素中,这样做的主要目的就是把所有外部文件(包括CSS文件和JavaScript 文件)的引用都放在相同的地方,方便管理

但是,这样做意味着必须等到全部JavaScript代码都被下裁、解析和执行完成以后,才能开始呈现页面的内容(浏览器在遇到<body>标签时才开始呈现内容),有可能会导致页面呈现出现延迟

因此把<script>元素放在闭标签</body>之前,这样,在解析JavaScript代码之前,页面的内容已经完全加载

4. <noscript>元素

当浏览器不支持JavaScript或者用户禁用了JavaScript功能时,才会将该元素中的内容显示出来,该元素使用的唯一目的也正是如此(元素内部可以嵌套除了script元素之外的任何元素)

五. JavaScript基本语法

1. 字符集

JavaScript使用Unicode字符集(统一码、万国码——支持所有语言)

HTML、CSS使用的是UTF-8

2. 大小写

JavaScript中的一切——变量、函数名、关键字以及所有标识符,都区分大小写

3. 空格和换行

JavaScript会忽略程序中标识之间多余的空格和换行

因此可以采用整齐,一致的缩进来形成统一的编码风格,提高代码可读、可维护性

4. 标识符

标识符是指变量、函数、属性的名字,或者函数的参数

标识符需符合以下规则

  • 标识符是由字母、数字、下划线、美元符号组成的字符序列
  • 第一个字符不能是数字

通常我们只使用ASCII字母(a~z,A~Z)和数字(0~9)来书写标识符,然后,要知道的是,JavaScript允许标识符使用Unicode字符全集中的字母和数字(当然包括汉字)

此外,标识符建议采用驼蜂大小写格式书写(第一个字母小写,剩下的每个有意义的单词的首字母大写,这样与内置的函数和对象命名保持一致,是一种最佳实践)

strong、getName、setAgeFull、

不能把关键字、保留字、true、false、null等用作标识符

5. 关键字和保留字

关键字(特殊用途)和保留字(留做特殊用途)不能用作标识符或者对象属性,在此不再列举

估计没有谁会把保留字或者关键字用做标识符,因为保留字或者关键字都比较常见,退一万步讲,编辑器也会给予高亮提示的

ECMAScript 5规定:关键字和保留字不能用作标识符,但可以用作对象的属性名,呵呵哒,谁爱用谁用

6. 注释

//  这是 单行注释,不可换行

/*  
 *这是多行注释,可多行,但不可嵌套
 *为了提高多行注释的可读性
 *最好每一行都以星号开头
 */	

注释的适当应用可以提高代码的可读性、可维护性,并且还可以用来调试程序

7. 严格模式——IE9及以下浏览器不支持

ECMAScript 5引入了严格模式( strict mode),对ECMAScript 3中的一些不确定的行为进行了规范

只需在代码顶部使用如下代码即可开启严格模式

"use strict";
//开启严格模式
//这是一个编译指示(pragma ),不属于JavaScript代码
//仅仅表示将JavaScript 引擎切换到严格模式

在函数顶部包含这条编译指示,可以仅让该函数在严格模式下执行

function doSome(){ 
	"use strict";   //只在该函数内部开启严格模式
}

"use strict";是一条编译指示,不是语句,对于不支持的浏览器,它什么也不做,不产生副作用

8. 语句

JavaScript的语句以分号结束(控制语句除外),但如果语句各自独占一行,那么分号是可选的,如果省路了分号,则由解析器来确定语句的结尾

通常的规则是——当前语句和下一语句无法合并解析时,JavaScript才会在第一行后填补分号

var
a
=
3;    //解析为 var a = 3;

总是给语句加上分号是一个最佳实践——可以增强可读性、(轻微的)提高代码的性能(解析器就不用自己判断分号位置了)、避免出现BUG、还可以放心压缩代码

之所以说可以避免BUG,是因为,如果下一行的第一个字符是下面这五个字符之一

(      [      /     +      - 

JavaScript将不对上一行句尾添加分号(因为可以合并解析)

var x = y
(function (){ ....})(); 
等同于
var x = y (function (){...})();         //出错

因此,在写立即执行函数的时候,总是在函数前加上分号,这样哪怕之前的语句不小心省略了分号,也不会出错

;(function(){

})();

上面提到,当前语句和下一语句无法合并解析时,JavaScript才会在当前语句后填补分号,但有两个例外

首先就是return、break、continue语句

return 
true;     //解析为 return; true;

也就是return、break、continue和之后的表达式之间不能有换行

另外一个例外就是自增和自减运算符

x
++
y

总是解析为 x;++y;(前缀)

所以说,语句结尾的分号不是必需的,但任何时候都不要省略它

9. 代码块{ }

代码块用于组织多条语句

虽然条件控制语句(如if语句)只在执行多条语句的情况下才要求必须使用代码块,但最佳实践是始终在控制语句中使用代码块——即使代码块中只有一条语句(这样增加代码的可读性、可维护性)

10. 字面量(直接量)

字面量(直接量),就是程序中直接使用的数据值

12               //数字字面量
"hello"        //字符串字面量
true           //布尔值字面量
[1,2,3]        //数组字面量
{name:"strong"}     //对象字面量
/[Ss]trong/      //正则表达式字面量

11. 变量(简介)

JavaScript是松散类型(弱类型)的语言,同一个变量可以用来保存任何类型的数据

每个变量仅仅是一个用于保存值的占位符而已,更确切的说,是内存中的一块空间

声明变量

定义(声明)变量使用var运算符,后跟一个标识符

var myName; //声明但未初始化,自动获得undefined值

也可以在定义(声明)变量时直接赋值(初始化)

var myName = "zsz";  //声明并初始化
myName = 12 ;           //修改变量值和类型,有效但不推荐

初始化变量并不会把变量标记为某种数据类型,初始化的过程就是给变量赋一个值那么简单(更本质的说,就是向变量对应的存储空间中存入一个值),变量是无类型的,类型说的只是变量中保存的值,所以永远不要说某个变量是什么类型的,而应该说该变量保存的值是什么类型的

同时声明多个变量

可以使用一条语句定义多个变量,只要把每个变量(初始化或不初始化均可)用逗号分隔开

var  myName = "zsz" ,  //换行和缩进,提高可读性
myAge = 24,
yourName;

不经过声明的变量

变量也可以不经声明,直接使用,只需要省略var运算符即可,与使用var声明的变量相比,有如下不同:

  • 使用var运算符定义的变量将会成为定义该变量的作用域中的局部变量(例如函数内的局部变量在函数退出后就会被销毁,因而在函数外部无法访问);省略var运算符将会创建全局变量(全局变量不易维护,如有意创建全局变量,应注释清楚)
  • 使用var声明的变量会提升到当前作用域的顶端(赋值仍在原位置进行),未经声明直接使用的变量不会提升(后详述)
  • 使用var声明的变量,不能使用delete删除,未经声明的变量,可以使用delete删除
  • 在严格模式下,必须使用var声明变量,给未经声明的变量赋值会抛出ReferenceError错误

此外还要注意这样一种情况

var a=b=3;

赋值运算从右往左,因此相当于

b=3;        //无意中创建了一个全局变量,谨慎
var a=b;

你可能感兴趣的:(JavaScript)