词法结构字符集使用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.2let y=0.2-0.1x==y // falsex==0.1 // falsey==0.1 // true// 由于舍入误差,0.3和0.2之间的近似差值实际上不等于0.2和0.1之间的近似差值文本字符串是一组由16位值组成的不可变的有序序列。字符串长度是其所含的16位值的个数。转义字符布尔值true或者false可转换为false的值:undefined、null、0、-0、NaN、’’。null和undifinedtypeof 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,并返回计算前的值。,逗号运算符,从左到右一次执行,返回最右边的值关系表达式ininstanceof逻辑表达式赋值表达式其他运算符?:typeofdeleteviod,逗号运算符,从左到右计算,最后返回最右边的值语句声明语句变量var let函数function条件语句switchswitch(expression){ statements}// expression中计算是使用===循环do/whiledo{ 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/catchtry{ xxxx}catch(e){ xxx}finally{ xxx}对象创建对象对象直接量创建的对象原型为Object.prototype通过new创建的对象原型为使用的原构造函数的prototypeObject.create()创建的对象原型为第一个参数,也可设置为null属性的查询和设置属性访问错误查询属性和原型有关,设置与原型无关(如果设置属性为继承属性,且具有setter方法时,将执行setter,而不是给当前对象创建新的属性)下列情况给对象O设置属性P会失败O中属性P是只读的(defineProperty()方法中有例外)O中的P是继承的,且是只读的O中不存在属性P,O中没有使用setter方法继承属性P,并且O的可扩展性()是false检测属性in:x in ohasOwnProperty: 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,而是不存在// 三种方式创建// 1new Array(5)// 2a=[]a[1000]=0// 3delete 数组方法标识为变异方法joinreverse *sort *concatslicesplice *,返回删除元素组成的数组push/unshift ,返回数组新的长度pop/shift * 返回删除元素的值toString/toLocalString 无方括号,逗号分隔forEachmapfilter,可以使用来压缩稀疏数组every 所有元素调用判定函数,均返回true才返回truesome 所有元素调用判定函数,有一个返回true就返回truereduce/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、callapply 将函数作为指定对象thisObj的方法来调用,传递给它的是指定的参数数组argsfunction.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)toStringFunction()构造函数,最后一个实参为函数体函数式编程高阶函数操作函数的函数,接收一个或者多个函数作为参数,并返回一个函数。不完全函数传入bind()的实参都是放在传入原始函数的实参列表开始的位置。作用域分类全局函数,块级(ES6+)eval作用域链变量对象用于存储执行上下文中的:变量函数声明函数参数1.变量初始化阶段2.代码执行阶段类和模块特性:封装、继承、多态、抽象类名使用大驼峰命名。ES6直接使用class,下面是ES6之前的。构造函数和类的标识原型对象是类的唯一标识:当切仅当两个对象继承自同一个原型对象时,它们才属于同一个类的实例。construsctor构造函数是类的公共标识,construsctor属性为对象提供了类。let 0= new F()0.construsctor===F // => truejavascript中的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方法searchreplacematchsplitRegExp对象属性:sourceglobalignoreCasemultilinelastIndex方法:exectestjavascript的子集和扩展迭代迭代器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从句E4Xjsx语法