# JS 基础

# 主流浏览器内核

浏览器主要由 shell 和内核组成。shell 是浏览器的那些界面,命令,给用户操作的

浏览器 内核
IE trident
Chrome blink
Firefox Gecko
Safari webkit
Opera presto

# JavaScript 组成

  • 核心(ECMAScript)
  • 文档对象模型(DOM)--->是针对 XML 但经过扩展用于 HTML 的 API
  • 浏览器对象模型(BOM)

&

如果页面中 script 标签中既引入了外部的 js 文件,又嵌入了 js 代码,则嵌入的代码会被忽略

# JavaScript 执行步骤

  1. 语法分析
  2. 预编译
  3. 解释执行

# 变量类型

  1. 基本类型值(存放在里)
    • Number
      • 浮点数值,保存浮点数值的内存空间是保存整数值的两倍,如 1.0 这样的浮点数会被转换成整数 1
      • NaN(非数值),与任何值都不相等
        • 判断一个变量是否是 NaN 时,不能用 x == NaN ,而应当用 x != x 来判断,只有当 x = NaN 时才会返回 true ,函数 isNaN() 与此类似
      • 数值转换:
        • Number() 用于任何类型
        • parseInt() 把字符串转换成整数类型,遇到第一个不是数字的字符串停止
        • parseFloat() 把字符串转换成浮点数数类型,遇到第一个不是数字的字符串停止
      • 任何类型的数据与 Number 类型进行数学运算时,都会被转换成数字,不能转换成数字的就是 NaN
    • String
      • 字符串一旦被创建他们的值就不能被改变,如果要改变就必须销毁原来的字符串,再用一个新的来填充该变量
    • Boolean
    • undefined
      • 已声明但未被初始化的变量值为 undefined
    • null
      • null == undefined 结果为 true
  2. 引用类型值(存放在里)
    • array
    • object
    • function
    • ...

&

基本类型值在栈里面存放数据,变量之间的赋值是通过拷贝副本,此后两个变量可以参加任何操作而不会相互影响;引用类型值存放在堆里,包含引用类型值的变量实际上包含的是指向该对象的指针

  1. typeof 操作符:检测变量的数据类型

    • 返回的值有六种(全是字符串类型
      • 'number'
      • 'string'
      • 'boolean'
      • 'object'
      • 'undefined'
      • 'function'
    • typeof(123) => 'number'
    • typeof(typeof(123)) => 'string'
    • 如果 typeof 返回了 undefined 则有可能是以下三种情况
      • var a = undefined
      • var b
      • 未定义
  2. instanceof 操作符:检测变量属于哪一种引用类型

  • 左操作数是一个对象,右操作数是标识对象的类
  • 如果左侧的对象是右侧类的实例,则返回 true,否则返回 false
  • 工作原理:
    • 为了计算 o instanceof f
    • 首先计算 f.prototype
    • 然后在原型链中查找 o
    • 如果找到,那么 o 就是 f(或者 f 的父类)的一个实例,返回 true
    • 如果 f.prototype 不在 o 的原型链中,则 of 就没有派生关系,返回 false
  • 使用 instanceof 操作符的问题在于:
    • 单一的全局环境
    • 如果网页中有多个框架,那么就有多个全局环境,就存在多个环境下的构造 函数
  1. 关于 && 操作符:
  • 大多数情况下都是对表达式进行布尔计算
  • 另一种情况:运算符首先计算左侧的值
    • 如果为 false,那么整个表达式也是 false,就不会对右侧的表达式进行计算,这时就返回左侧表达式的值
    • 如果为 true,那么整个表达式就会返回右侧表达式的结果
    • var p = null
    • p && p.x // 返回null
  1. i++ 和 ++i

    • i++ 是先执行表达式语句再运算

    • ++i 是先运算再执行表达式语句

    • var i = 1
      var a = i++ + 1
      var b = ++i + 1
      a // 2
      b // 4
      
    • 分析:执行第二行语句时,i = 1,所以 a = 2,执行完这个语句,i + 1,所以 i = 2;执行第三行语句时,先把 i + 1,此时 i = 3,最后结果 b = 4

# 相等与全等

  1. 使用 ==,不同类型的值也可以被看作相等(可以允许类型转换)
类型(x) 类型(y) 结果
null undefined true
数字 字符串 x == toNumber(y)
布尔值 任何类型 toNumber(x) == y
字符串或数字 对象 x == toPrimitive(y)

toNumber() 对不同类型返回的结果如下:

值类型 结果
undefined NaN
null 0
布尔值 true = 1,false = 0
字符串 如果字符串包含字母,返回 NaN,如果是数字组成,返回数字
对象 Number(toPrimitive(obj))

toPrimitive() 转换对象时:

如果对象的 valueOf 方法的结果是原始值,返回原始值;如果对象的 toString 方法返回原始值,就返回这个值;其他情况都是错误

  1. 使用 === 操作符

如果比较的两个值类型不同,比较的结果就是 false;如果值类型相同,就要比较两个值是否一致(引用的同一个对象

&

所有的大写 ASCII 字母都小于小写的 ASCII 字母

# 类型转换

布尔值的转换

数值类型 转换成布尔值
undefined false
null false
布尔值 true/false
数字 +0、-0 和 NaN 是 false,其他是 true
字符串 空字符串是 false,其他是 true
对象 true

&

JavaScript 中的任何值都可以转换成布尔值,其中只有六个转换为 false

# 隐式类型转换

隐式类型转换在内部调用的是显示类型转换

  • isNaN(n) => Number(n)
  • ++/-- => Number()
  • 如果 + 运算符的一个操作数是字符串,它会把另一个操作数转换为字符串=> String()
  • 四则运算=> Number()
  • undifined == null

# 对象转布尔值

所有的对象(包括数组和函数)都将转换为 true,对于包装类型也一样:new Boolean(false) 也将转换为 true

# 对象转字符串和数字

所有的对象都继承了 toString()valueOf() 方法

  1. toString()
    • 作用是返回一个反映这个对象的字符串
    • ({x:1}).toString() => [object Object]
    • [1, 2, 3].toString() => 1, 2, 3
    • (function() {}).toString => function() {}
    • ...
    • nullundifined 没有 toString() 方法
  2. valueOf()
    • 简单的返回对象本身
    • 日期对象会返回 1970/1/1 以来的毫秒数

JavaScript 对象到基本类型的转换经历了以下过程:

  • 对象首先会调用 valueOf() 方法,一般对象的 valueOf() 方法都会返回这个对象的本身,如果返回的是一个原始值,那么直接将这个结果返回
  • 如果返回的不是一个原始值,对象就会去调用 toString() 方法,如果返回的是一个我原始值,就将这个结果返回
  • 否则就会抛出异常

&

对于 +== 运算符,如果其中一个操作数是对象,JavaScript 就会将对象转换为原始值

# Date

var date = new Date();

  • getFullYear方法:得到年份
  • getMonth方法:得到月份,从0开始计算
  • getDate方法:得到日期部分
  • getDay方法:得到星期几,0表示星期天
  • getHours方法:得到小时部分
  • getMinutes方法:得到分钟部分
  • getSeconds方法:得到秒部分
  • getMilliseconds方法:得到毫秒部分
  • getTime方法:得到时间戳

# 垃圾回收机制

# 标记清除(最常用)

垃圾回收器在运行时给所有在内存中的变量都加上标记,然后它会去掉环境中的变量被环境中的变量引用的变量的标记,而在此之后加上标记的被视为准备删除的变量

# 引用计数

当声明了一个变量并将引用类型值赋给这个变量,则这个值的引用次数为1;如果这个值又被赋给另一个变量,则引用次数+1;如果引用这个值的变量又取得了另一个值,则引用次数-1,直到引用次数为0,就会被回收

# 基本包装类型

JS 为了增强原始类型的功能,为 boolean、string、number 分别创建了一个构造函数:

  1. Boolean
  2. String
  3. Number

&

每当读取一个原始类型的时候,后台会通过构造函数创建一个与之对应的原始类型对象,通过这个对象来访问原始类型的属性和方法

引用类型与基本包装类型的主要区别就是对象的生存期

使用new操作符创建的引用类型的实例,在执行流离开当前作用域之前一直保存在内存中。而自动创建的基本包装类型的对象,只存在于一行代码的执行瞬间,然后立即被销毁。就意味着不能给基本包装类型的对象添加属性和方法

使用new调用的构造函数和直接调用同名的转型函数是不一样的:

var value = "23";
var obj = new Number(value);	//构造函数
typeof obj			---->		"object"
var number = Number(value);		//转型函数
typeof nunber		---->		"number"

# 单体内置对象

内置对象:不依赖宿主环境,在程序执行之前就已经存在了

  1. Global 对象:不属于任何对象的属性和方法最终都是 Global 的
    • URI 编码
      • encodeURI():使用它编码后的结果是除了空格之外的其他字符都原封不动,只有空格被替换成了 %20
      • encodeComponentURI():替换所有非字母数字的字符
      • 一般对整个 URI 使用 encodeURI,对附加在 URI 后面的字符串使用 encodeComponentURI
      • decodeURI 和 decodeComponentURI 能够对上面两种编码之后的解码
    • eval()
      • eval() 中定义的代码对当作实际的 ECMAScript 代码来解析,然后把执行结果插入到原来的位置,被执行的代码具有与该执行环境相同的作用域链。
      • eval() 中创建的任何变量或函数都不会被提升,只有在执行的时候才创建
  2. Math 对象:
    • random()
      • 在给定范围内取值:(min,max)max 一般取不到
      • value = Math.random() * (max - min) + min

# 错误处理

# 抛出错误

if(false) {
    throw 错误对象;
}

# 捕获错误

try {
    //代码块1
}
catch(错误对象) {
    //代码块2
}
finally {
    //代码块3
}
更新: 3/28/2020, 9:40:55 AM