javaScript高级程序设计-读书笔记

强化js基础,来看一看传说中的小红书

1.JavaScript 简介

JavaScript的实现

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

ECMAScript

宿主:

  • WEB浏览器
  • Node平台
  • Adobe Flash

大致组成部分:

  • 语法
  • 类型
  • 语句
  • 关键字
  • 保留字
  • 操作符
  • 对象

文档对象模型(DOM)

是真的XML但经过扩展用于HTML的应用呈现变成接口(API)。DOM把整个页面映射为一个多层节点结构。

浏览器对象模型(BOM)

2.HTML中使用javascript

script标签

6个属性:

  • async:可选。表示立即下载脚本,不妨碍页面其他操作;
  • charset: 可选。表示src属性指定代码的字符集;
  • defer: 可选。表示脚本可以延迟到文档完全被解析和显示之后再执行。只外部脚本有效;
  • src: 可选。表示包含要执行代码的外部文件;
  • type: 可选。表示编写代码使用的脚本语言内容类型,不指定默认为text/javascript;
  • language:已废弃。

使用script元素的两种情况:直接在页面嵌入javascript代码 和 包含外部javascript。

带src属性的script元素不应该在其script标签之间包含额外的javascript代码。只会下载并执行外部脚本文件,嵌入的代码会被忽略。

script元素的src属性还可以包含来自外部域的javascript文件与img元素的src属性相似。(可以利用这一点进行跨域请求),同时也要考虑安全性。

只要存在defer和async属性,浏览器会按照script元素在页面中出现的先后顺序对他们一次解析。

标签的位置

  • 传统做法:放在head元素中。

    但这样会影响页面呈现,等javascript代码被下载解析执行完成以后才开始呈现页面内容·。

  • 现在web应用:放在body元素页面内容后面

解析javascript代码之前,页面内容将完全呈现

延迟脚本

defer属性: script标签放在head中也会将script脚本延迟到标签后执行(只适用于外部脚本)

异步脚本

async属性:异步下载和执行script脚本(注意:互相有依赖关系的脚本不适用,因为无法保证加载顺序)

3.基本概念

语法

区分大小写

例如: test和Test是两个不同的变量。

标识符

就是指比变量、函数、属性的名字或函数的参数。

  • 第一个字符必须是字母、下划线_或一个美元符号$
  • 其他字符可以是字母、下划线、美元符号或数字

按照惯例ECMAScript标识符采用驼峰大小写格式。

注释
  • // 单行注释

  • /*

    *多行注释

    *啦啦啦

    */

严格模式

ECMAScript 5引入严格模式。

顶部添加“use strict”

语句

推荐语句结尾写分号 ; (我就不写分号…)

单句if判断推荐写花括号;

关键字和保留字

不能作为标识符(也就是声明的变量名)

关键字

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 ** **

保留字:尽管在这门语言中没有任何特定用途,但他们有可能将来被用作关键字

abstract enum int short
boolean export interface static
byte extends long super
char final native synchronized
class float package throws
const goto private transient
debugger implements protected volatile
double import public

非严格模式下保留字有缩减

数据类型

  • 5种基本数据类型: Undefined、Null 、Boolean、Number、String。
  • 一种复杂类型: Object
typeof操作符

检测数据类型的一种手段,返回的结果如下

  • “undefined”(值未定义)
  • “boolean”(布尔类型)
  • “string”(字符串类型)
  • “number”(数值类型)
  • “object”(对象或null)
  • “function”(函数)
undefined类型

声明未赋值时

未声明也未定义的变量,访问时会报错

但typeof操作符会返回”undefined”

Null类型

空对象指针

所以typeof返回“object”

如果定义变量准备将来用于保存对象,那么最好将该变量初始化为null而不是其他值。这样直接判断!=null就可以指定相应变量是否保存了一个对象引用。

Boolean类型

两个字面量:true和false

转换Boolean类型(Boolean())

数据类型 转换为true值 转换为false值
Boolean true false
String 任何非空字符串 “” 空字符串
Number 任何非零数字值(包含无穷大) 0和NaN
Object 任何对象 null
undefined undefiend

if语句会隐式转换boolean

Number类型

ECMAScript能保存的

最小数值存在于Number.MIN_VALUE中,大多数浏览器中这个值时5e-324

最大数值保存在Number.Max_VALUE中,大多数浏览器中这个值时1.7976931348623157e+308

如果某次结果得到一个超出javascript数值范围的值,那么这个数值将被自动转换成特殊Infinity值。

负数 -Infinity (负无穷)

正数 Infinity(正无穷)

将无法参与下一次计算

NaN

非数值,一个特殊数值,这个数值用于表示一个本来要返回数值的操作数未返回数值的情况。

  • ECMAScript中,任何数值除以0会返回NaN
  • NaN与任何值都不相等包括自身

isNaN()函数,可以确定这个参数是否“不是数值”,接收到一个值后,尝试将这个值转换为数值例如字符串“10”或Boolean值,而任何不能被转换为数值的值都会导致这个函数返回true

数值转换

Number()

  • true和false将被转换为1和0

  • 如果时数字值只是简单的传入与返回

  • 如果是null返回0

  • 如果是undefined返回NaN

  • 如果是字符串,遵循以下规则

    • 如果字符串中只包含数字则转换为数字‘012’会转换为12,0前面的会被忽略

    • 如果字符串中包含有效浮点格式如“1.1”则转换为1.1,0在前的话同样忽略

    • 如果包含有效的十六进制格式,则转换为相同大小的十进制整数值

    • 如果字符串是空,则转换为0

    • 如果字符串中包含除以上格式之外的字符则转换为NaN

  • 如果是对象,则调用对象的valueOf()方法然后依照前面的规则进行转换返回的值。如果转换的结果是NaN,则调用对象的toString()方法,然后再次依照前面的规则转换返回的字符串值。

parseInt()

忽略字符串前面的空格,直到找到第一个非空字符串,如果不是数字字符或者符号返回NaN

如果第一个字符是数字字符会继续解析第二个,知道解析完所有后续或者遇到非数字字符。不解析小数

parseFloat()

与parseInt()类似但遇到小数点会继续解析,知道遇到第二个小数点

String类型

包含一些特殊的字面量

字面量 含义
\n 换行
\t 制表
\b 空格
\r 回车
\f 走纸换页
\ \ 斜杠
\ ‘ 单引号
\ “ 双引号
\xnn
\ unnnn
字符串特点

ECMAScript 中字符串是不可变的,也就是说,字符串一旦被创建,值不能改变,要改变某个变量保存的字符串,首先要销毁原来的字符串,然后在用另一个包含新值的字符串填充该变量。

转换为字符串

toString()

null和undefined没有这个方法

在不确定是否为null或undefined的情况下,还可以使用转型还是String(),遵循以下原则:

  • 如果值有toString()方法则调用该方法并返回结果
  • 如果是null则返回null
  • 如果是undefined则返回undefined
Object类型

ECMAScript中对象其实就是一组数据和功能的集合。对象可以通过new操作符后跟要创建的对象类型的名称来创建。

Object的每个实例都具有下列属性和方法

  • constructor: 保存用户创建当前对象的函数。
  • hasOwnProperty:用于检查给给定的属性在当前对象实例中(而不是在实例的原型中)是否存在。传入的参数必须以字符串形式指定
  • isprototypeOf(object): 用于检查传入对象是否是传入对象的原型
  • propertyIsEnumerable(propertyName): 用于检查给定的属性是否能使用for in 语句来枚举
  • toLocaleString() : 返回对象的字符串表示
  • valueOf(): 返回对象的字符串,数值或布尔表示,通常与toString()方法的返回值相同

操作符

一元操作符
  1. 递增和递减操作符

    1
    // 前置和后置的++ --
  2. 一元加和减操作符

    1
    // 前置+或-

    隐式转换数值类型

位操作符
  1. 按位非(NOT)

    由~表示,执行按位非的结果就是返回数值的反码。按位非是ECMAScript操作符中少数几个与二进制计算有关的操作符之一。

    1
    2
    3
    var num1 = 25; // 二进制 00000000000000000000000000011001 
    var num2 = ~num1; // 二进制 11111111111111111111111111100110
    alert(num2); // -26

    按位非操作的本质:操作数的负值减 1。

  2. 按位与(AND)

    由&表示

    按位与操作只在两个数值的对应位都是1时才返回1,任何一位是0,结果都是0.

    1
     
  3. 按位或(OR)

    由|表示

    按位或操作在有一个位是1的情况下返回1,两个都为0的情况下才返回0

先略过位操作符(理解无能)

布尔操作符
  1. 逻辑非(!)

    首先将它的操作数转换为一个布尔值,在对其求反

    两个!!实际上就是模拟转换布尔

  2. 逻辑与 &&

    • 如果第一个操作数能够决定结果,那么就不会在对第二个操作数求值
    • 如果第一个操作数是false,则无论第二个操作数是什么值,结果都不再可能是true
    • 两个都为true的就返回第二个,都为false返回第一个,一个为false返回false的那个
  3. 逻辑或||

    • 第一个为true返回第一个
    • 第一个为false,第二个为ture返回第二个
    • 第一个为false, 第二个为false 返回第二个false

返回最终起决定因素的那个&&最终决定为false的,|| 最终决定为true的,都不满足就只好返回第二个

语句

if语句

判断语句 搭配else 或else if

do while语句

一种后测试循环语句

先执行一次再测试条件

适用于循环体中的代码至少要被执行一次的情形

while语句

前测试循环语句,循环体内执行之前对出口条件求值

for语句

前测试循环语句,循环之前初始化变狼和定义循环后要执行的代码。

for in 语句

精准的迭代语句,可用来枚举对象的属性。

1
2
3
for (let key in window) {
document.write(key)
}

for in 循环输出的属性名的顺序是不可预测的

要迭代的对象的变量值为null或undefined,则不执行循环体。所以在使用前检测该对象的值不是null或undefined

break 和 continue语句

用于循环中精确控制代码执行,break立即跳出循环,continue立即退出进行下一次循环

with语句

严格模式下不允许使用with语句 否则视为语法错误

switch语句

switch语句在比较值的时候使用的是全等操作符,因此不会发生类型转换

多个if elseif 时使用switch比较好

函数

推荐的做法是要么让函数始终都返回一个值,要么永远都不要返回值。

但其实写业务代码时是根据场景来的

理解参数

ECMScript函数不介意传递进来多少个参数,也不在乎传进来参数是什么类型。

原因是ECMscript中的参数在内部使用一个数组来表示的。

arguments对象是类数组,所以可以使用[0]访问也有length属性。

没有重载

ECMScript 函数不能像传统意义上那样实现重载。例如JAVA可以为一个函数编写两个定义。

ECMScript中同名函数会被后一个覆盖,但我们可以通过检查传入的参数的类型和数量并作出不同的反应,模仿方法的重载。

4.变量、作用域和内存问题

基本类型和引用类型

  • 基本类型: Nndefined、Null、Boolean、Number、String。
  • 引用类型: 对象,数组。

检测类型

typeof操作符是确定一个变量是字符串,数值,布尔值,还是undefined的最佳工具。

如果变量是一个对象或null,则typeof操作符会返回object。typeof检测函数时会返回function.

检测引用类型时可以使用instanceof,如果变量是给低昂引用类型的实例,那么instanceof会返回true。

根据规定,所有引用类型的值都是object的实例,因此在检测一个引用类型值和object构造函数时,会返回true。

执行环境和作用域

在web浏览器中,全局执行环境被认为是window对象,因此所全局变量和函数都是作为window对象的属性和方法创建的。

每个函数都有自己的执行环境。

标识符解析是沿着作用域链一级一级的搜索标识符的过程。搜索过程始终从作用域链的最前端开始,然后逐级向后回溯,直至找到标识符为止,如果找不到标识符,通常会导致错误发生。

函数参数也被当作变量来对待,因此其访问规则与执行环境中的其他变量相同。

垃圾收集

javascript具有自动垃圾收集机制,也就是说,执行环境会负责管理代码执行过程中使用的内存。

简单的原理:找出那些不再继续使用的变量,然后释放其占用的内存。为此垃圾收集器会按照固定的时间间隔,周期性的执行这一操作。

局部变量只有在函数执行的过程中存在。而在这个过程中,会为局部变量在栈或堆上分配相应的空间,以便存储它们的值。然后在函数值使用这些变量,知道函数执行结束。释放局部变量。

标记清除

当变量进入环境,例如函数中声明一个变量时,标记为进入环境。逻辑上来讲永远不能释放进入环境的变量,当变量离开环境时,则将其标记为离开环境。

引用计数

不太常见的一种垃圾收集策略。

当一个值的引用次数为0时,可以将其回收。

管理内存

确保占用最少的内存可以让页面获得更好的性能。而优化内存占用的最佳方式,就是执行中的代码只保存必要的数据。一旦不再有用,最好通过将其值设置为null来释放其引用。

不过接触一个值的引用并不意味着自动回收该值所占用的内存。接触引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收。

5.引用类型

Object类型

声明方法: new关键字和字面量

访问方法: 点或[]

[]可以用来访问会导致语法错误的字符,或者属性名使用的是关键字或保留字。

Array类型

检测数组

  • instanceof
  • Array.isArray()

转换方法

  • toString() toLocaleString() valueOf() 返回,分隔的字符串

  • join() 可以使用不同的分隔符构建这个字符串

    如果数组中某一项值是null或undefined,那么这句个方法返回的结果以空字符串表示

栈方法

  • push 从数组末尾添加
  • pop 从数组末尾移除一项

重排方法

  • reverse 翻转数组项的顺序
  • sort() 默认从小到大排序,也可以传入函数,按照函数的规则排序

操作方法

  • concat 基于当前数组中所有项创建一个新数组。
  • slice
  • splice

位置方法

  • indexOf
  • lastIndexOf

迭代方法

  • every
  • filter
  • forEach
  • map
  • some

归并方法

  • reduce
  • reduceRight(

Date类型

date类型使用UTC 1970年1月1日零时开始经过的毫秒数来报错日期,能够精确到1970年1月1日之前或之后的285616年

new Date() 创建日期对象

Date.parse()方法接受一个表示日期的字符串参数,尝试返回相应的毫秒数。如果传入的字符串不能表示日期会返回NaN.

超多API暂时忽略

RegExp类型

匹配模式3个标志

  • g: 表示全局,应用于所有字符串,而非发现第一个匹配项时立即停止;

  • i: 表示不区分大小写,在确定匹配项时忽略字符串大小写;

  • m: 表示多行,即到达一行文本末尾时还会继续查找下一行中是否存在与模式匹配的项;

  • 元字符必须转义:([{\^$|)?*+.]})

面向对象的程序设计

小结

  • 工厂模式,使用简单的函数创建对象,为对象添加属性和方法,然后返回对象。这个模式后来被构造函数模式所取代;

  • 构造函数模式,可以创建自定义引用类型,可以像创建内置对象实例一样使用new操作符。不过,构造函数也有缺点,即它的每个成员都无法得到复用,包括函数。由于函数可以不局限于任何对象,因此没有理由不在多个对象见共享函数。

  • 原型模式,使用构造函数的prototype属性来指定那些应该共享的属性和方法。组合使用公祖奥函数模式和原型模式时,使用构造函数定义实例属性,而使用原型定义共享属性和方法

    原型链的问题是对象实例共享所有继承的属性和方法,因此不适宜单独使用。解决这个问题的技术是借用构造函数,即子类型构造函数内部调用超类型构造函数。这样可以做到每个实例都具有自己的属性,同时还能保证只使用构造函数模式来定义类型。

函数表达式

小结

  • 函数表达式不同于函数声明,函数声明要求有名字,但函数表达式不需要。没有名字的函数表达式也叫做匿名函数。

  • 在无法确定如何引用函数的情况下,递归数就会变得比较复杂

    ...表示看不下去了

------ 本文结束------
0%