JavaScript高程学习笔记(一)

116 阅读9分钟

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等
      • 箭头函数、期约、反射、代理。

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;
  • 两个函数的参数不能叫同一个名称。