JavaScript权威指南笔记(上)-语言核心

词法结构

字符集

使用Unicode编写

  • ES3 Unicode2.1+
  • ES5 Unicode3+

区分大小写

注释

// 注释

/*
注释
*/

标识符和保留字

必须以字母、下划线、美元符开始,后续字符可以是字母、数字、下划线、美元符,即数字不能作为首字符

保留字



可选的分号

Javascript只有在缺少了分号就无法正确解析代码的时候才会填补分号。

一般,一条语句以(、[、/、+、-开始,它极有可能和前一条语句一起解析。return、break、continue除外

类型、值和变量

数据类型:在编程语言中、能够表示并操作的值的类型

变量:一个值的符号名称,可以通过该名称获得值的引用。

数据类型

一般分类

  • 原始类型:数字、字符串、布尔值、null、undefined
  • 对象(属性的键值对集合)类型:数组、普通对象、函数类、日期类、正则类、错误类

其他分类

  • 可以拥有方法的类型和不能拥有方法的类型
  • 可变类型(数字、布尔值、null、undifined、字符串)和不可变类型(对象、数组)

数字

javascript采用IEEE 754标准定义的64位浮点格式表示数字,最大值±1.7976931348623157E+308,最小值±5E-324

能够表示的整数范围为-2E+53~2E+53。实际操作(如数组索引)是基于32位整数。

注意: 小数精度问题,如0.1+0.2 != 0.3 ,需要转成整数计算,计算完成再转回小数。产生原因是Number采用的时IEEE 754 64位双精度浮点数编码,浮点数无法精确表示其值范围内的所有数值,导致十进制转换成二进制时有舍入模式,产生了误差

格式

  • 整形直接量
  • 浮点直接量

算术运算

上溢出(正负无穷)使用±Infinity表示,下溢出(无限接近于0)则返回0(±0)。

NaN和任何值都不相等,包括自身。

二进制浮点数和四舍五入错误

在javascript使用实数时,常常只是真实值的一个近似表示。

let x=0.3-0.2
let y=0.2-0.1
x==y // false
x==0.1 // false
y==0.1 // true
// 由于舍入误差,0.3和0.2之间的近似差值实际上不等于0.2和0.1之间的近似差值

文本

字符串是一组由16位值组成的不可变的有序序列。字符串长度是其所含的16位值的个数。

转义字符

布尔值

true或者false
可转换为false的值:undefined、null、0、-0、NaN、''。

null和undifined

  • typeof null为object,含义为非对象
  • undifined 未定义值

全局对象

全局属性、全局函数、构造函数、全局对象

包装对象

存取字符串、数字或布尔值的属性时创建的临时对象叫包装对象。

不可变的原始值和可变的对象引用

可变类型(数字、布尔值、null、undifined、字符串)和不可变类型(对象/引用类型、数组)。

类型转换

转换和相等性

显式类型转换






变量声明

如果给一个未声明的变量赋值(不可配置),实际上会给全局对象创建一个同名属性(可配置),不建议这样用。

创建一个全局变量实际上是给全局对象创建了一个属性。

变量作用域

一个变量的作用域是程序源代码中定义这个变量的区域。

  • 函数作用域、块级作用域。
  • 声明提前

类型检测

  • typeof 用于基础类型和函数判断
  • instanceof用于对象类型判断
  • Object.prototype.toString.apply([])==='[object Array]' null、undifined失效

表达式和运算符

表达式

表达式分为简单表达式(常量、变量名)和复杂表达式(由简单表达式组成)。

原始表达:

表达式的最小单位,

  • 直接量(包括:数字、字符串、布尔,不包括数组、对象)
  • 关键字
  • 变量

由简单表达式可以组合成复合表达式

复杂表达式

  • 对象和数组的初始化表达式
  • 函数定义表达式
  • 属性访问表达式
  • 调用表达式
  • 对象创建表达式

运算符

说明:

  • 下图按照优先级高到低排序,水平线分割的具有不同的优先级
  • A列表示运算符结核性,L(左到右) R(右至左)
  • N列表示操作数的个数
  • 类型列表示期望的操作数类型以及运算符的结果类型


分类

按照操作数个数分:一元(+1)、二元(1+2)、三元(?:)

左值

表达式只能出现在赋值运算符的左侧。变量、对象属性、数组元素均是左值。

算术表达式

一元算术运算符

作用于一个单独的操作数,并产生一个新值,具有很高的优先级,且均为右结合。

  • +:转换为数字或者NaN,并返回转换后的值
  • -:和+一样,但是会改变结果的符号。
  • ++--:运算符在操作数前,操作数±1并返回计算后的值;运算符在操作数之后,操作数±1,并返回计算前的值。
  • ,逗号运算符,从左到右一次执行,返回最右边的值

关系表达式

  • in
  • instanceof

逻辑表达式

赋值表达式

其他运算符

  • ?:
  • typeof
  • delete
  • viod
  • ,逗号运算符,从左到右计算,最后返回最右边的值

语句

声明语句

  • 变量var let
  • 函数function

条件语句

switch

switch(expression){
    statements
}
// expression中计算是使用===

循环

do/while

do{
   statements 
} while(expression)
// 至少执行一次

for/in

// 将对象中的所有属性复制到一个数组中
var o = {x:1,y:2,z:3};
var a = [], i = 0;
for(a[i++] in o) /* empty */;

跳转

标签语句

mainloop: while(token I= null) { 
// 忽略这里的代码...
continue mainloop; //跳转到下一次循环
// 忽略这里的代码...
}
//从标签名开始,以便在报错时退出程序
compute_sum: if (matrix) { 
    for(var x = o; x < matrix.length; x++) { 
        var row= matrix[x]; 
        if (!row) break compute_sum; 
        for(var y = o; y < row.length; y++) { 
            var cell= row[y]; 
            if (isNaN(cell)) break compute_sum; sum+= cell; 
        }
    }
    success= true; 
}
// break语句跳转至此II如果在success== false的条件下到达这里, 说明我们给出的矩阵中有错误//否则将矩阵中所有的元素进行求和

其他语句类型

width

// 临时扩展作用域链
with(document.form[0]){
    name.value=""
}

try/catch

try{
    xxxx
}catch(e){
    xxx
}finally{
    xxx
}

对象

创建对象

  • 对象直接量创建的对象原型为Object.prototype
  • 通过new创建的对象原型为使用的原构造函数的prototype
  • Object.create()创建的对象原型为第一个参数,也可设置为null

属性的查询和设置

属性访问错误

查询属性和原型有关,设置与原型无关(如果设置属性为继承属性,且具有setter方法时,将执行setter,而不是给当前对象创建新的属性)

下列情况给对象O设置属性P会失败

  • O中属性P是只读的(defineProperty()方法中有例外)
  • O中的P是继承的,且是只读的
  • O中不存在属性P,O中没有使用setter方法继承属性P,并且O的可扩展性()是false

检测属性

  • in:x in o
  • hasOwnProperty: O.hasOwnProperty(x)
  • propertyIsEnumerable: o.propertyIsEnumerable(x),hasOwnProperty的增强版,自身属性且可枚举
  • o.x!==undefined x的值为undefined则需要使用in

属性的特性

  • 值 value
  • 可写性 writable
  • 可枚举性 enumerable
  • 可配置性 configurable
获取自身属性的特性
Object.getOwnPropertyDescriptor({x:1},'x')
// 返回{value:1,writable:true,enumerable:true,configurable:true}
设置属性的特性
// 单个
Object.definePeoperty(o,'x',{
    value:1, // 值
    writable:true, // 可读
    enumerable:true, // 可遍历
    configurable:true // 可改变配置
})
// 批量
Object.definePeoperties(o,{
    x:{
        value:1,
        writable:true,
        enumerable:true,
        configurable:true
    },
    y:{
        value:1,
        writable:true,
        enumerable:true,
        configurable:true
    }
})

对象的三个属性

原型

  • 查询原型Object.getPrototypeOf()
  • 检测是否包含某个原型p.isPrototypeOf(o),p是否是o的原型

类属性

可以通过toString获取对象的类属性

function classof(o){
    if(o===null) return 'Null';
    if(o===undefined) return 'Undefined';
    return Object.prototype.toString.call(o).slice(8,-1);
}
classof({}) // => 'Object'

可扩展性

  • 查询可扩展性 Object.isExtensible(o)
  • 转换成不可扩展 Object.preventExtensions(o)
  • 封闭:转换为不可扩展且所有属性不可配置 Object.seal(),可使用Object.isSealed()来检测是否封闭
  • 冻结:转换为不可扩展且所有属性不可配置、所有属性只读 Object.freeze(),可以使用Object.isFrozen()来检测是否冻结

序列化

JSON.stringify(),JSON.parse()具可接受第二个参数,标识需要序列化或还原的属性列表

对象方法

  • toJSON()
  • valueOf()将对象转换成原始值

数组

创建数组

  • 数组直接量[],该语法有可选的结尾逗号,故[,,]只有两个元素而非三个
  • new Array()
new Array() // 创建一个空数组
new Array(10) // 创建一个长度为10的数组
new Array(5,4,3) // 创建一个已包含数组元素数组

稀疏数组

稀疏数组并不是项的值为undefined,而是不存在

// 三种方式创建
// 1
new Array(5)
// 2
a=[]
a[1000]=0
// 3
delete 

数组方法

*标识为变异方法

  • join
  • reverse *
  • sort *
  • concat
  • slice
  • splice *,返回删除元素组成的数组
  • push/unshift *,返回数组新的长度
  • pop/shift * 返回删除元素的值
  • toString/toLocalString 无方括号,逗号分隔
  • forEach
  • map
  • filter,可以使用来压缩稀疏数组
  • every 所有元素调用判定函数,均返回true才返回true
  • some 所有元素调用判定函数,有一个返回true就返回true
  • reduce/reduceRight
// 求和、第二个参数为temp的初始值,不传默认使用数组中的第一个元素
arr.reduce((temp,value,index,arr)=>temp+value, 0)
  • indexOf/lastIndexOf

数组类型

判断使用Array.isArray(arr)判断是否是数组

函数

构造函数:用于初始化一个新创建的对象的函数

函数定义

两种定义方式及区别:

  • 函数声明语句,可以在定义前使用(函数声明前置);不能出现在循环、条件、try/catch/finally、with中
  • 函数定义表达式,不能在定义前使用(变量声明前置);可以出现在任何地方
  • 函数构造器

函数调用

四种调用方式:

  • 作为函数:this在非严格模式为全局对象,严格模式为undefined
  • 作为方法:this为方法所属对象
  • 作为构造函数:this为新构造的对象
  • call()或者apply()间接调用:this为指定的对象

函数的实参与形参

不定实参函数:可以接收任意个数的实参,通过arguments(类数组对象)接收参数

作为命名空间的函数

立即调用函数

(function(){
    
}())

闭包



词法作用域,函数内变量作用域是在函数定义时创建的,而不是在调用时创建,且在函数执行时,定义时的作用域链依然有效。
函数对象可以通过作用域链相互关联起来,函数体内部的变量都可以保存咋子函数作用域内,这种特性叫闭包。

函数属性、方法和构造函数

length 形参个数

arguments 参数对象(类数组对象)

prototype 指向原型对象

apply、bind、call

  • apply 将函数作为指定对象thisObj的方法来调用,传递给它的是指定的参数数组args
function.apply(thisObj,args)
  • call 将函数作为指定对象thisObj的方法来调用,传递给它的是指定的参数,如果thisObj为null,则为全局对象
function.call(thisObj,arg1,arg2,...)
  • bing 返回一个新函数,通过可选的指定参数,作为指定对象obj的方法调用该方法,传递给该函数的参数由两部分组成,一部分是传递给bind()的args数组指定的参数,剩下的是传给这个新函数的所有值。

传入bind()的实参都是放在传入原始函数的实参列表开始的位置。

function.call(obj,arg1,arg2,...)
// 示例:
let g=f.bind(obj,1,2)
g(3)
// 等价于
f.call(obj,1,2,3)

toString

Function()构造函数,最后一个实参为函数体

函数式编程

高阶函数

操作函数的函数,接收一个或者多个函数作为参数,并返回一个函数。

不完全函数

传入bind()的实参都是放在传入原始函数的实参列表开始的位置。

作用域

分类

  • 全局
  • 函数,块级(ES6+)
  • eval

作用域链

变量对象

用于存储执行上下文中的:

  • 变量
  • 函数声明
  • 函数参数
1.变量初始化阶段

2.代码执行阶段

类和模块

特性:封装、继承、多态、抽象

类名使用大驼峰命名。ES6直接使用class,下面是ES6之前的。

构造函数和类的标识

原型对象是类的唯一标识:当切仅当两个对象继承自同一个原型对象时,它们才属于同一个类的实例。

construsctor

构造函数是类的公共标识,construsctor属性为对象提供了类。

let 0= new F()
0.construsctor===F // => true

javascript中的java式的类继承


创建一个类分为三步:

  • 定义一个构造函数,并设置初始化新对象的实例属性
  • 给构造函数的prototype对象定义实例方法
  • 给构造函数定义类字段和类属性

类的扩充

javascript中基于原型的继承机制是动态的,如果创建对象之后原型的属性发生变化,也会影响到继承这个原型的所有实例,即我们可以通过给原型对象添加方法来扩充Javascript类。

类和类型

instanceof:
obj instanceof c 
obj.isPrototypeOf(f)
constructor:
x.constructor===Number
构造函数的名称
Object.prototype.toString.call(o)

注意:

  • 前两种方法在多个执行上下文无效
  • 这三种方法都有一个问题,就是不是所有对象都有constructor属性
鸭式辩型

Javascript中的面向对象技术

标准转换方法

  • toString()
  • toLocaleString()
  • valueOf()
  • toJSON()

方法借用

Object.prototype.xxx=xxx

子类

  • 方法链
  • 构造函数链

正则表达式的匹配模式

定义

  • 直接量
  • 构造器

内容

直接量字符

字符类

重复

非贪婪重复在匹配字符后加一个?即可。

选择、分组、引用

指定匹配位置

修饰符

String方法

  • search
  • replace
  • match
  • split

RegExp对象

属性:
  • source
  • global
  • ignoreCase
  • multiline
  • lastIndex
方法:
  • exec
  • test

javascript的子集和扩展

迭代

迭代器

Iterator(),返回迭代器

for(let [k,v] in Iterator({a:1,b:2}))
console.log(k+"="+v)   // a=1,b=2

特性:

  • 只针对自有属性进行遍历,忽略继承属性
  • 第二个参数传true,则只遍历属性名。忽略值

数组推导*

[expression for (varuable in object) if(conditon)]

函数简写

表达式闭包:如果函数只计算一个表达式并返回它的值,关键字return和花括号可以省略

let succ=function(x)x+1

多catch从句

E4X

jsx语法

你可能感兴趣的:(javascript)