资讯专栏INFORMATION COLUMN

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

skinner / 3070人阅读

摘要:二进制浮点数和四舍五入错误在使用实数时,常常只是真实值的一个近似表示。作用域分类全局函数,块级作用域链变量对象用于存储执行上下文中的变量函数声明函数参数变量初始化阶段浏览器截图浏览器截图代码执行阶段类和模块

词法结构 字符集

使用Unicode编写

ES3 Unicode2.1+

ES5 Unicode3+

区分大小写 注释
// 注释

/*
注释
*/
标识符和保留字

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

保留字

QQ浏览器截图20181126125600
QQ浏览器截图20181126125600
QQ浏览器截图20181126125655

可选的分号

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位值的个数。

转义字符

微信截图_20181126223425

布尔值

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

null和undifined

typeof null为object,含义为非对象

undifined 未定义值

全局对象

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

包装对象

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

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

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

类型转换

微信截图_20181126223425

转换和相等性

微信截图_20181126223425

显式类型转换

微信截图_20181126223425
微信截图_20181126223425
微信截图_20181126223425
微信截图_20181126223425
微信截图_20181126223425
微信截图_20181126223425

变量声明

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

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

变量作用域

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

函数作用域、块级作用域。

声明提前

类型检测

typeof 用于基础类型和函数判断

instanceof用于对象类型判断

Object.prototype.toString.apply([])==="[object Array]" null、undifined失效

表达式和运算符 表达式

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

原始表达:

表达式的最小单位,

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

关键字

变量

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

复杂表达式

对象和数组的初始化表达式

函数定义表达式

属性访问表达式

调用表达式

对象创建表达式

运算符

说明:

下图按照优先级高到低排序,水平线分割的具有不同的优先级

A列表示运算符结核性,L(左到右) R(右至左)

N列表示操作数的个数

类型列表示期望的操作数类型以及运算符的结果类型

QQ浏览器截图20181127131052
QQ浏览器截图20181127131052

分类

按照操作数个数分:一元(+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中

函数定义表达式,不能在定义前使用(变量声明前置);可以出现在任何地方

函数构造器

QQ浏览器截图20181202215231

函数调用

四种调用方式:

作为函数:this在非严格模式为全局对象,严格模式为undefined

作为方法:this为方法所属对象

作为构造函数:this为新构造的对象

call()或者apply()间接调用:this为指定的对象

函数的实参与形参

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

作为命名空间的函数

立即调用函数

(function(){
    
}())
闭包

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

函数属性、方法和构造函数 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()构造函数,最后一个实参为函数体 函数式编程 高阶函数

操作函数的函数,接收一个或者多个函数作为参数,并返回一个函数。
微信截图_20181126223425

不完全函数

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

作用域 分类

全局

函数,块级(ES6+)

eval

作用域链 变量对象

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

变量

函数声明

函数参数

1.变量初始化阶段

QQ浏览器截图20181202223314

2.代码执行阶段
类和模块

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

类名使用大驼峰命名。ES6直接使用class,下面是ES6之前的。
QQ浏览器截图20181128130544

构造函数和类的标识

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

construsctor

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

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

QQ截图20181130130049

javascript中的java式的类继承

TIM截图20181202165528
创建一个类分为三步:

定义一个构造函数,并设置初始化新对象的实例属性

给构造函数的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
子类

方法链

构造函数链

正则表达式的匹配模式 定义

直接量

构造器

内容
直接量字符

QQ浏览器截图20181128124924

字符类

QQ浏览器截图20181128125033

重复

非贪婪重复在匹配字符后加一个?即可。
QQ浏览器截图20181128125033

选择、分组、引用

QQ浏览器截图20181128125325

指定匹配位置

QQ浏览器截图20181128125414

修饰符

QQ浏览器截图20181128125434

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语法

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100895.html

相关文章

  • JavaScript 权威指南》读书笔记 1 - 简介

    摘要:原文第一章主要介绍的大概情况基本语法。通过和来引用对象属性或数组元素的值就构成一个表达式。 原文:https://keelii.github.io/2016/06/16/javascript-definitive-guide-note-0/ 第一章 主要介绍 JavaScript 的大概情况、基本语法。之前没有 JavaScript 基础的看不懂也没关系,后续章节会有进一步的详细说明...

    sydMobile 评论0 收藏0
  • PHPer书单

    摘要:想提升自己,还得多看书多看书多看书下面是我收集到的一些程序员应该看得书单及在线教程,自己也没有全部看完。共勉吧当然,如果你有好的书想分享给大家的或者觉得书单不合理,可以去通过进行提交。讲师温铭,软件基金会主席,最佳实践作者。 想提升自己,还得多看书!多看书!多看书!下面是我收集到的一些PHP程序员应该看得书单及在线教程,自己也没有全部看完。共勉吧!当然,如果你有好的书想分享给大家的或者...

    jimhs 评论0 收藏0
  • 双十二大前端工程师读书清单

    摘要:本文最早为双十一而作,原标题双大前端工程师读书清单,以付费的形式发布在上。发布完本次预告后,捕捉到了一个友善的吐槽读书清单也要收费。这本书便从的异步编程讲起,帮助我们设计快速响应的网络应用,而非简单的页面。 本文最早为双十一而作,原标题双 11 大前端工程师读书清单,以付费的形式发布在 GitChat 上。发布之后在读者圈群聊中和读者进行了深入的交流,现免费分享到这里,不足之处欢迎指教...

    happen 评论0 收藏0
  • 双十二大前端工程师读书清单

    摘要:本文最早为双十一而作,原标题双大前端工程师读书清单,以付费的形式发布在上。发布完本次预告后,捕捉到了一个友善的吐槽读书清单也要收费。这本书便从的异步编程讲起,帮助我们设计快速响应的网络应用,而非简单的页面。 本文最早为双十一而作,原标题双 11 大前端工程师读书清单,以付费的形式发布在 GitChat 上。发布之后在读者圈群聊中和读者进行了深入的交流,现免费分享到这里,不足之处欢迎指教...

    余学文 评论0 收藏0

发表评论

0条评论

skinner

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<