1.什么是javascript
是用来与网页交互的脚本语言,由ECMAScript,BOM,DOM组成。
- 背景:验证某个字段是否已填,需要与服务器的一次往返通信。
- 目的:主要用途是代替Perl等服务器语言处理输入验证。
- 发展:JavaScript应用不再局限于数据验证,而是渗透到浏览器窗口及内容的方方面面。
- 功能:实现复杂的计算与交互,包括闭包,匿名函数,甚至元编程等。
1.1历史回顾
发展过程中,为验证简单的表单需要大量与服务器往返通信逐渐成为用户痛点。
1995年,网景公司的Brendan Eich工程师开始为即将发布的Netscape Navigator2开发了一个叫Mocha(改名为LiveScript)的脚本语言。计划是客户端和服务端都使用它,它在服务器中叫LiveWire。为了赶上发布时间,网景与Sun公司联盟开发,在Netscape Navigator2正式发布前,网景为蹭Java的热度,将LiveScript改名为JavaScript。
Javascript1.0很成功,因此网景又在Netscape Navigator 3发布了1.1版本。此时微软发布IE3其中包含自己命名为JScript的JavaScript实现。1996年8月微软重磅进入Web浏览器领域。
1997年。JavaScript1.1作为提案被提交给欧洲计算机制造协会(ECMA)。该协会打造出ECMA-262,也就是ECMAScript这个新的脚本预压。
1998年,国际标准化组织(ISO)和国际电委歇会(IEC)也将ECMAScript采纳为标准(ISO/IEC-16262)
1.2Javascript实现
JavaScript不限于ECMA-262定义的那样,完整的JavaScript包含以下几部分。
- 核心(ECMAScript)
- 文档对象模型(DOM)
- 浏览对象器模型(BOM)
ECMAScript
是由ECMA-262定义的语言,并不局限于浏览器,其宿主环境还有服务器端JavaScript平台Node.js
- 定义了:语法,类型,语句,关键字,保留字,操作符,全局对象。
- 重要版本介绍:
- 第3版,对语言标准进行了更新。
- 更新了字符串处理、错误定义和数值输出。
- 此外增加了正则表达式、新的语句控制、try/catch异常处理。
- 标志着ECMAScript作为一门真正的编程语言时代的到来。
- 第5版,厘清歧义,增加新功能。
- 原生解析和序列化数据的JSON对象;
- 方便继承和高级属性定义的方法;
- 以及新的增强ECMAScript引擎解释和执行代码能力的严格模式
- 第6版,ES6、ES2015,有史以来最重要的一批增强特性。
- 支持了类、模块
- 迭代器、生成器、新型数据Set Map等
- 箭头函数、期约、反射、代理。
- 第3版,对语言标准进行了更新。
DOM
是一个应用编程接口(API),DOM通过创建表示文档的树,让开发者可以控制网页内容和结构。使用DOM API可以增删查改节点。
- DOM级别:
- DOM Level1目标是映射文档结构。
- DOM Level2目标宽泛,增加了鼠标和用户界面事件、范围、变量的支持,通过对象接口支持层叠样式表。
- DOM Leval3进一步扩展DOM,增加了统一的方式加载和保存文档的方法。还有验证文档的方法。
BOM
用于支持 访问和操作浏览器的窗口。主要针对浏览器窗口和子窗口及特定于浏览器的扩展。
- 主要包含:
- 弹出新窗口能力
- 移动缩放和关闭浏览器窗口能力
- Navigator对象,提供浏览器的详尽信息
- location对象,提供浏览器加载页面的详尽信息
- screen对象,提供关于用户屏幕分辨率的详尽信息
- performance对象,提供浏览器内存占用、导航行为和时间统计的详尽信息
- 对cookie的支持
- 其它自定义对象,如XMLHttpRquest和IE的ActiveXObject
1.3释义
元编程:编写操纵程序的程序。例如Proxy,Reflect拦截并定义基本语言操作的自定义行为(属性查找,赋值,枚举,函数调用等)
2.HTML中的Javascript
2.1<script> 元素
提供该元素用于引入JavaScript。
有8个属性:async,charset(很少使用),crossorigin(跨域),defer,intergrity(安全相关),language(废弃),src,type(module当ES6)。
- async:立即下载脚本,不会阻塞页面,下载完成阻止执行脚本。(仅支持外部脚本文件)
- defer:立即下载脚本,不会阻塞页面,下载完成等DOM解析完成后执行脚本完成后,DOMContentLoaded事件触发。(仅支持外部脚本文件)
动态加载脚本:创建script元素,设置src并将其挂载到DOM上。创建的脚本默认默认增加了async属性为true,可以设置为false用以兼容不支持的浏览器。 这种方式获取资源对浏览器的预加载器是不可见的,影响性能,需要显示声明。
<link rel="preload" hre="demo.js" />
2.2行内代码与外部元素
尽可能使用外部文件,因为在可维护性,缓存及适应未来方面优与行内代码。
2.3文档模式
最初文档有标准模式和混杂模式。通过doctype来切换模式。
2.4<noscript>
对浏览器不支持脚本或浏览对脚本的支持被关闭的情况下,用于向用户展示说明下文字。其它情况下该内容不会渲染。
3.语言基础
3.1语法
主要涵盖:区分大小写,标识符,注释,严格模式,语句。
3.2关键字保留字
不能用作标志符和属性名称。
3.3变量
声明方式:var,let,const
3.4数据类型
分为简单数据类型和复杂数据类型,简单类型通过typeof进行判断,复杂类型通过instanceof来判断。
- 简单数据类型:undefined、null、Boolean、Symbol、String、Number、BigInt
- 复杂数据类型:Object。
Undefined
声明了变量没有初始化。
null
表示一个空对象指针。表面上与undefined相等。
Boolean
不同类型与布尔值之间的转换规则:
- String 非空字符串为true,空字符串为false
- Number 非零数值为true,0和NaN为false
- Object 任意对象为true,null为false
- Undefined 为false
Number类型
1.浮点值
浮点值存储空间是整数值的两倍,因此ECMAScript总是想方设法将其转为整数。对于非常大或小的浮点数可以通过科学计数法表示。
let f = 3.125e7 //表示3125000
浮点数的精确度最高达17位小数,但是在算数计算中不如整数精确。比如0.1+0.2实际得到的是0.30000000000000004。由于微小的舍入错误很难测试特定的浮点值。
0.1 + 0.2 != 0.3 // true
2.值的范围
- 最大最小值:Number.MIN_VALUE、Number.MAX_VALUE
- 正负无穷大:Infinity、-Infinity、isFinite()
3.NAN
- 0除以任意值都返回NaN
- 任何值除以0,都会返回Infinity或者-Infinity。
- isNaN()判断是否为NaN。
4.数值转换 有三个函数可以将非数值转为数值:Number() parseInt() parseFloat()
- Number转换规则
- 布尔值 true转1,false转0
- null返回0
- undefined返回NaN
- 字符串规则
- 字符串包含数值,数值前加减号转十进制,忽略数值前的0。
- 字符串包含浮点数,则转换为相应浮点数
- 如果数字包含有效的十六进制格式,则转换为与该十六进制对应的十进制数值。
- 如果是空字符串则返回0
- 其它情况返回NaN
- 对象调用valueOf方法按上述规则转换返回的值,若为NaN则调用toString方法按上述规则进行转换。
- parseInt转换规则(专注于字符串是否包含数值)
- 忽略字符串前面的空格
- 如果第一个字符不是数值字符,加减号,返回NaN。
- 因此空字符串也会返回NaN。
- 若第一个字符是数值字符或加减号,会依次检查字符,碰到非数值字符返回。
- 可以解析把兼职和十六进制,转为十进制。
- 支持第二个参数指定进制。
let num1 = parseInt('12345blue') //12345
let num2 = parseInt('') //NaN
let num3 = parseInt('0xA') // 10
let num4 = parseInt('012') // 10
let num5 = parseInt('10', 2) //2
- parseFloat转换规则
- 类似parseInt(),不同是只解析十进制。
String类型
表示零个或多个16位Unicode字符序列。
- 字符串的特点,字符串是不可变的。
- 转换为字符串的方法为toString(),接收进制参数,将字符串转为对应进制。
- 模板字面量可以跨行定义字符串,字符串插值可以插入变量。
- 模板字面量标签函数。参数为原始字符串数组,和插值表达式值。
let a = 6;
let b = 9
function simpleTag(string, para1, para2, para3) {
console.log(string) // ['','+','','=','']
console.log(para1, para2, para3) // 6,9,15
return 'foo'
}
simpleTag `${a}+${b}=${a+b}`
- 原始字符串,通过String.raw 标签函数获取
console.log(String.raw `\u00A9`) // \u00A9
Symbol类型
用途是确保对象属性使用唯一的标识符,不会发生属性冲突的危险。
- 基本用法:使用Symbol初始化函数
- 全局注符号注册表:使用Symbol.for()方法。使用Symbol.keyFor()来查询全局注册表。
- 使用符号作为属性:对象字面量属性,Object.defineProperty()/Object.defineProperties()定义的属性。
let s1 = Symbol('foo');
let s2 = Symbol('bar');
let s3 = Symbol('baz');
let o = {
[symbol]: 'foo val'
}
Object.defineProperty(o, s2, {value: 'bar val'});
Object.defineProperties(o,{
[s3]: {value: 'baz val'}
})
- Object.getOwnPropertySymbols() 返回对象实例的符号属性数组。
- 常用内置符号:用于暴露语言内部行为。
- Symbol.iterator属性,在for-of循环时会使用。
- ...
Object类型
实际是一组数据的功能的集合。 属性和方法:
- constructor:用户创建当前对象的函数。
- hasOwnProperty(propertyName)
- isPropertyOf()
- propertyIsEnumrable()
- toLocalString()
- toString():返回对象的字符串表示。
- valueOf():返回对象对应的字符串、数值或布尔值表示。
3.5操作符
主要包含:一元操作符、位操作符、布尔操作符、加减乘除操作符、指数操作符、加性操作符、关系操作符、相等操作符、条件操作符、赋值操作符、逗号操作符。
3.6语句
主要包含:if do-while while for for-in for-of 标签语句 break和continue with switch
- for-in 枚举对象中的非符号键属性。(可枚举,非符号,自身和原型上的属性)
- for-of 变量可迭代对象的元素。
3.7函数
严格模式下限制:
- 函数不能以eval或arguments作为名称;
- 函数不能叫eval或arguments;
- 函数采纳数不能叫eval或aguments;
- 两个函数的参数不能叫同一个名称。