@FunC
2017-10-30T11:09:50.000000Z
字数 5171
阅读 2244
JavaScript
JavaScript 诞生于1995年,最早由Netscape 实现,主要用于解决表单验证。JavaScript 成功之后,因为缺乏统一的标准,导致市面上存在多个不同的JavaScript 实现。为了解决这个问题,EMCA指定39号技术委员会(TC39)负责“标准化一种通用、跨平台、供应商中立的脚本语言的语法和语义”。最终的成果就是ECMA-262——名为ECMAScript 的新脚本语言标准。
JavaScript = ECMAScript + DOM + BOM
ECMAScript-262 给出的ECMAScript 兼容的定义是:
1. 支持ECMA-262 描述的所有“类型、值、对象、属性、函数以及程序语句和语义“
2. 支持Unicode 字符标准。(从而支持多语言开发)
值得注意的是,兼容的实现还可以进行如下扩展:
1. 添加ECMA-262 没有描述的”更多类型、值、对象、属性和函数“。(主要为标准中没规定的新对象和属性)
2. 支持ECMA-262 没有定义的”程序和正则表达式语法“。(即可修改和扩展内置的正则表达式语法)
文档对象模型(DOM,Document Object Model)把整个页面映射为一个多层节点结构,并提供API 供开发者对节点进行删除、添加、修改等操作。
DOM并不只针对JavaScript,其它的语言如SVG、MathML、SMIL都发布了只针对自己的DOM标准。
IE 5.5~8 : DOM 1级(几乎全部);IE 9+:DOM 1~3级
从根本上讲,BOM只处理浏览器窗口和框架,但习惯上还包括针对浏览器的JavaScript 扩展,如:
* 弹出新浏览器窗口的功能
* 移动、缩放和关闭浏览器窗口的功能
* 提供浏览器详细信息的navigator 对象
* 提供浏览器所加载页面的详细信息的location 对象
* 提供用户显示器分辨率详细信息的screen 对象
* 对cookies 的支持
* 像XMLHttpRequest 和 IE 的 ActiveXObject 这些自定义对象
通过 标签在HTML 页面中引入 JavaScript。其中又分为直接在页面中嵌入 JavaScript 代码和包含外部JavaScript 文件。
如果直接在 元素中嵌入代码时,注意不能在任何地方出现 、“”字符串,必须用转义字符”\”将”/”字符转义。
使用外部JavaScript 文件时,可跨域,且.js扩展名不是必须的(但注意服务器能返回正确的MIME 类型)。
使用外部脚本被认为是更好的做法,可提高代码的维护性,并使同一份JavaScript 能够被缓存
解析HTML 时,遇到<script>
标签,会将对象的JavaScript 下载、解析、执行完成后再进行接下来的解析,所以为了让页面尽快展示,一般将<script>
标签放在 </body>
前。
HTML 4.01中为<script>
标签定义了defer 属性(仅适用于外部脚本)。能让浏览器立即下载脚本,并延迟至整个页面解析完毕后执行(但先于DOMContentLoaded 事件执行)。
根据标准,多个延迟脚本应按照出现顺序依次执行,但现实中不一定按顺序执行。
HTML5 中为<script>
标签定义了async 属性。异步脚本立即下载,并且不阻塞HTML 的解析。下载完毕后马上执行。
注意:延迟脚本和异步脚本中都不能使用document.write()
对于不支持JavaScript 的浏览器,为了避免直接将JavaScript 代码直接显示在页面中,JavaScript 通过支持HTML 注释语法来避免这个问题。即:
<script><!—
function sayHo() {
alert("Hi!");
}
//--></script>
不过现在所有浏览器都支持JavaScript 了,所以也没有必要用这种语法。
这种少见的语法还会造成一些奇怪的现象, 例如在控制台输入
1<!—5
会返回1,原因是1后面都是注释部分…
<noscript>
元素<noscript>
元素里的内容仅在浏览器不支持/禁用 JavaScript 脚本时显示。
主要有:
1. 混杂模式(quirks mode) -> 让IE 行为与IE5 相同
2. 标准模式(standards mode)
3. 准标准模式(almost standards mode)
如果无文档类型声明,默认开启混杂模式。
在HTML 5 中,只需要写<!DOCTYPE html>
且不区分大小写。
该章仅记录平时较少使用或易忽略的点
关键字:break, do, instanceof, typeof, case, else, new, var, catch, finally, return, void, continue, for, switch, while, debugger, function, this, with, default, if, throw, delete, in, try, eval, arguments
保留字:class, enum, extend, super, const, export, import, implements, package, public, interface, private, static, let, protected yield
关键字和保留字不能用作标识符。
松散类型,若省略var
操作符可以定义去全局变量。
原用于检测变量类型,但返回的结果不总是准确,现在一般用于检测变量是否已定义:
// 下面变量age 没有声明
alert(typeof age); // “undefined”
需要检测变量类型可使用, Object.prototype.toString.call()。此方法从ECMAScript 5.1 开始能正确检测所有类型
只有一个值undefined。变量已声明但未初始化时的默认值。
只有一个值null。惯例作为空对象指针。
只有两个字面值:true和false。区分大小写。
值得注意的是:true不一定等于1,false不一定等于0。
采用IEEE754 格式表示整数和浮点数。
可以保存正零(+0)和负零(-0),一般被认为相等。使用Object.is时判定为不等。
Number.MIN_VALUE
和Number.MAX_VALUE
中Infinity
或者-Infinity
isFinity()
函数判断Infinity
数值转换
Number()
(一元加操作符与其功能相同):
parseInt()
(第二个参数为基数):
原理是检查字符串是否符合数值模式,从第一个非空格字符开始,直到下一个非数字字符结束。
值得注意的情况有:
parseInt("") // NaN
parseInt("1234blue") // 1234
parseFloat()
(只解析十进制值,无第二个参数):
* 与parseInt()
的不同的地方在于第一个小数点是有效的
String 类型用于表示由零或多个16位Unicode 字符组成的字符串。
1. 字符字面量
转义序列:1. \xnn 以十六进制代码nn表示的一个字符,如\x41表示“A”;2. \xnnnn 以十六进制代码nnnn表示的一个Unicode 字符
2. 字符串特点
ECMAScript中的字符串是不可变的:
var str = "hello";
str[0]; // "h"
str[0] = "b";
str; // "hello"
String()
方法.toString()
方法。注意null和undefined没有这个方法,而数值的toString()
方法的参数为基数。主要的属性和方法:
* constructor: 创建当前对象的函数
* hasOwnproperty(propertyName): 检查给定属性是否在当前对象实例中
* isPrototypeOf(object): 检查传入对象是否是当前对象的原型
* propertyIsEnumerable: 检查给定属性是否能够用for-in循环
* toString(): 返回对象的字符串表示。
* valueOf(): 返回对象的字符串、数值或布尔值表示。
值得注意的是,BOM和DOM中的对象属于宿主对象,不在ECMA-262的定义范围。所以可能不会继承自Object
递增/递减操作符
* 应用于true和false时,先分别转换成1和0,再进行加减1操作
* 应用于对象时,先调用valueOf()方法,得到基本类型的值;如果结果是NaN,则调用toString()之后再进行递增/递减运算
一元加/减操作符
* 一元加=Number()
* 一元减=-Number()
位操作符不直接操作64位的值,而是先将64位的值转换成32位的整数,执行操作,再将结果转换为64位。(带来的副作用:NaN和Infinity 当作0来处理)
* 按位非 ~:取反码
* 按位与 &:同1才1,否则为0
* 按位或 | :有1则1,同0才0
* 按位异或 ^ :不同为1,相同为0
* 左移 << ;有符号右移 >> ;无符号右移 >>>
字符串比较时比较字符编码(如大写字母编码全小于小写字母编码)
若NaN 参与比较,结果必定是false
一图蔽之:
关于逗号操作符,有一个debug妙用:x => (console.log(x), false)
可配合break和continue语句,返回代码中的特定位置(通常用于退出循环嵌套)
var num = 0;
outermost:
for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
if (i == 5 && j == 5) {
break outermost;
}
}
num++;
}
比较值时使用全等操作符(===)
ECMAScript 函数不介意函数参数的数量和类型,可以通过arguments 对象获得传入的参数,其中arguments 为类数组。arguments.length 反映了实际传入的参数数量。
在非严格模式中,arguments 和形参绑定,保持同步;在严格模式下不同步。
因为没有函数签名,所以没有重载。
JSON 是JavaScript的一个严格子集。JSON语法可以表示简单值、对象和数组。
JSON 字符串必须使用双引号,JSON 对象的属性名也必须带双引号。
序列化JavaScript 对象时,所有函数及原型成员都会被有意忽略。且值为undefined 的任何属性都会被跳过。
该方法还有两个参数,分别用作过滤器和缩进控制:JSON.stringify(target[, filter][, indent])
* filter 为数组时,序列化结果仅包含数组中的属性;filter 为函数时,其参数分别为key和value
* indent 为数字时,代表缩进的空格数(<=10);为字符时, 使用该字符代替空格来作为缩进字符(字符长度<=10 字节)
序列化对象的顺序:
1. 如果存在toJSON方法且能取得有效的值,使用该方法。否则返回对象本身。
2. 如果含filter, 使用filter。
3. 对2中的结果进行格式化
4. 如果提供了indent,进行相应的格式化
同样有一个还原函数作为第二个参数,还原函数的参数也是key和value
注意:当还原函数return undefined 时,删除对应的属性。