学习教程 —— 使用浏览器客户端开发学习 JavaScript 基础(一)

一:能干什么

附:前端编程笔录


声明:写此博文,并不是为了显摆什么,仅是用于个人以后的复习学习,好记性不如烂笔头,东西多了就容易产生混肴,此博汇总了个人的日常工作学习整理内容,多数参考与官方文档,此文适合初学者,觉得对你有所帮助就收藏,对于各路大神大将,就麻烦一下,抬抬“腿”,绕绕道吧!


相信除了此片博文记录 JavaScript 的基础知识外,网上随便一搜索,大把大把的文章,视频教程也一大把,博主也是看着别人(例:阮大神的网络日志)的文章视频学习过来的,只是把自己的学习心得记录下来,关于如何去做学习关联笔记,博主觉得不要边看教程编写笔记,这种方式不好,即使你过后再去复习,你所能得到的知识只会少不会多,再就是边看教程编写笔记,仅是把官方上的一些已有东西给记录下来,并没什么实际意义(_~~实际工作中都是没事翻翻文档的)。每次看别的大神文章感觉多少都会有些收获,所以,就算是学习笔记,也是需要用心思考、用心去写的。


对于我们工作者来说,学习 JavaScript 是用来工作的,至于为什么学习它,间接的说是提高个人技能水平,提高处理工作项目的开发能力,说直白一点:就是为了拿更高的工资呗~

在这个如火如荼的社会,每天的繁重工作,哪有半点时光给你做学术研究什么的,几乎大多公司的现状都是:市场赶产品,产品赶研发,一切以进度为准。没功夫去深入研究我们学的是什么,它是从哪里来的,它要从哪儿去?哦弥陀佛,产品不要再发 BUG 修复任务啦,快要下班啦~~

呵呵,每到下班前,总是会有一大堆的 BUG 修复任务从测试发过来,从而导致太多的“义务班”啦。打铁还需自身硬,多看别的大神学术研究成功,多积累自身,此文着重记录 JavaScript 重点,避免误区,多方考量


回到问题原点:JavaScript 能干什么?

早期,它是用于处理浏览器不能与访问者进行互动的能力;如今,还可以开发移动 APP 应用(ionic-cordova、react-nactive、weex)、桌面应用(electron-react)以及服务端应用(NodeJs、Koa2),此篇博文仅针对浏览器客户端而言


语言简介

JavaScript 是互联网上最流行的脚本语言,这门语言可用于 HTML 和 web,更可广泛用于服务器、PC、笔记本电脑、平板电脑和智能手机等设备

  • JavaScript 是一种高级轻量型的 —— 解释性语言,是前端开发工程师用来呈现浏览器实现数据交互行为的一门非编程语言
  • JavaScript 是可插入 HTML 页面的脚本代码,可由所有的现代浏览器执行的脚本语言,它不受外界硬件设备、软件应用影响

运行原理


解析 JS 函数
用 LLInt 分析解释
使用基线编译
执行基线代码
执行 DFG 代码
执行 FTL 代码
用DFG编译
用FTL编译

组成结构


JavaScript 组成
ECMAS 核心对象
基础语法
流程结构
函数应用
面向对象
注释调试
BOM 浏览器对象
数据交互
离线存储
HTML DOM 对象
节点操作
节点渲染

  • ECMAS 是 JavaScript 核心语法标准,是由 ECMA 组织指定的一套脚本语言的标准,也符合 W3C 标准,目前使用最前沿版本是 ES 6+
  • HTML DOM 是 JavaScript 操作网页 HTML 树结构操作上的一套整理节点 API 文档,改变 HTML 树节点对象:内容、样式以及行为控制
  • BOM 对象是 JavaScript 操作浏览器对象模型管理的一套整理 窗体 API 文档,用于获取浏览器窗体信息或监听浏览器窗体的一些行为规则

初始体验

回顾一下 HTML 知识,如果我们需要通过一个链接跳转到百度页面,很明显,对于 HTML 而言,只需要使用一个超链接标签就可以,对于这种访问者通过鼠标点击触发的跳转,也可以看成是一次交互,将以下代码赋值生成一个静态的 HTML 网页文档:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JS 初始体验title>
head>
<body>
    <a href="http://www.baidu.com/" target="_self">百度一下a>
    <button onclick="window.open('http://www.baidu.com/', '_self')">百度一下button>
body>
html>

通过以下 HTML 代码执行效果,发现超链接和按钮点击都是同一样的效果——跳转到百度首页,其中按钮使用的是 JS 的方式跳转,代码分析:

  • HTML 超链接 a 标签具有 href 属性用于指定链接的目录地址,还有一个 target 指定的链接方式,默认 _self 本窗口打开
  • HTML 超链接 a 标签并没有写死 target 就已经默认在本窗口打开方式,说明 超链接 a 标签同样具有一个点击事件去触发链接跳转
  • 以面向对象的思维方式可以得到 HTML 的按钮 button 标签同样具有点击事件,只是没有隐藏表现出来,需要使用 onclick 去触发
  • 按钮 button 对象触发了点击 onclick 事件,执行了 BOM 浏览器内置对象 window 的 open() 方法,表示窗口以何种方式打开链接

引入方式

  • 行内执行:可以直接在 HTML 标签内部直接使用,但前提是需要一个事件去触发它才能被执行
  • 标签执行:同样也在 HTML 代码任意区域,通过使用 script 标签来编码,JavaScript 执行代码在 script 元素标签内
  • 引入执行:有点类似于 HTML 的样式表 CSS 引入一个外文件,知识对于 JavaScript 的引入还是使用的是 script 元素标签

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>我的第一个 JavaScript 练习title>
head>
<body>
    <script language="javascript">
    	document.write('Hello World');		// document 是一个 BOM,write() 是一个动作,组合表示将 'Hello World' 写到浏览器内
    script>
body>
html>
--------------------------------------------------------------------------------------------------------------------------------
# demo.js
document.write('Hello World');

# demo.html 在 HTML 中,通过 script 标签引入 dome.js 文件

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>我的第一个 JavaScript 练习title>
head>
<body>
    <script language="javascript" src="./demo.js">script>
body>
html>

注释语法

JavaScript 注释用来解释某段程序或某行代码是什么意思、什么作用,方便开发者之间的交流,注释内容不会被浏览器解析出来,常用于开发者模式中

  • 单行注释:// 后面的代码必须另启行,否则为注释内容
  • 多行注释:/**/ 注释内容从 /* 到 */ 之间的内容,也可以用于局部注释
  • 文档注释:/**… */ 常用于函数注释,用来解释函数体,类似于一个 API 文档
// document.write('Hello World'); 我已经不需要了这行代码了,这里把它给注释掉了
--------------------------------------------------------------------------------------------------------------------------------
function Person(name, age) {
     
	/*
	这点代码可以使用下方代码替换方式
	return {
		name: name,
		age: age
	};
	*/
	
	this.name = name;
	this.age = age;
}
--------------------------------------------------------------------------------------------------------------------------------
/**
 * [Person description]
 * @param {[type]} name [description]
 * @param {[type]} age  [description]
 */
function Person(name, age) {
     
	this.name = name;
	this.age = age;
}

二:基础语法

虽说 JavaScript 是一门非编程式语言,但它又具备编程思想,这也是因为 JavaScript 在设计之初参考了 Java 的设计思路所带来的捆绑思想,也间接的导致了前期的 JavaScript 受冷门对待。当然,时至今日,咸鱼也有翻身之时,如今的 JavaScript 已经如火如荼了,各种前端框架喷发(弱鸡,学不动啦_ ~~),使得 JavaScript 在软件行业语言占比简直扶摇直上,特变是 ES6+ 版本的发布,更是让 JavaScript 如虎添翼啦,而 JavaScript 越来越走向编程之路啦 ~~

在学好任何一门编程语言之前,前提是需要把基础搭好,夯实了地基才能把楼高,一定要把编程语言的第一步(基本语法)学好学透,不能被表样(语法是固定的)所迷惑,要不然学到后面会卡住 “瓶颈”,从而失去信心继续去深入,学习的基本法则是多看 —— 咱一个脑袋能比不上大众多个、多记 ——记录笔记,把对你有帮助的知识点记录下来,学习的积累,才能丰富知识,充实技能,闲聊至此,回到主题。

变量常量

千遍一律,学编程语言跟我们上课学数学一样,在学习加减法之前先学会数数,能把 100 数清了就开始学习加减乘除,然后是图形单位,再之后就是应用题,学数学知识是逐步提升的,学编程也是一样的道理,在学编程之前,同样先学会 “数数” —— 量()

量:测量东西体积多少的器物,像日常喝水的杯子、吃饭的碗等。使用一次性纸杯装满水后,大概有200毫升的水,每当我们口渴就会去喝点,结果纸杯里的水越来越少,我们把纸杯内实时减少的水数量称之为可变的量 —— 变量,而这个纸杯固定最多装200毫升的水量称之为常量,同样是水,以编程思想去理解就变成了两种不同性质的量,所以:

变量:是指能够发生改变的量

常量:是指固定不会改变的量

var cup = 200 | 167 | 122 | 86 | 44 | 0;				-- 变量:杯子的水被改变了
const CUP = 200;										-- 常量:杯子的水一直不变

咦,这里的 var 和 const 是什么东东,干啥用的?英语好的同学的可能以下就看的懂意思,英语不好的同学看不懂没关系,你只要知道它是英语就可以,不要认为是外星文就可以啦,哈哈 ~~

噔噔噔噔~~,有请我们的万能互联网工具【百度翻译】闪亮登场,把这两个单词复制进去翻译一下,会发现 var 译文:变量,const 译文:常量。尼玛,研究来研究去,原来是这两二货,没办法,英语不好,只能靠翻译来补脑

JavaScript 使用 var 运算符(variable 的缩写)给变量来定义声明变量名的

JavaScript 使用 const 运算符(constant 的缩写)给常量来定义声明常量名的

呃~~,好像漏掉了一个 “=”,数学中这个符号是等号,例:1 = 1,指左右两个的大小相等,但在 JavaScript 语言中却不是等于的关系,而是赋值关系,就是把右边的数量【专业术语:字面量】给左边的变量,cup = 200 相当于是把 200 毫升的水倒入这个杯子内

一个杯子不仅可以用来装水,还可以装其他的小物件:小图钉呀、小纸屑呀等,甚至你还可以用来装你的口水,厄,废物利用吗

var cup1 = '小图钉', cup2 = '小纸屑', cup3 = '你的口水';		-- 多个变量定义可使用一个 var,变量之间使用逗号隔开

内存机制

计算机 内一切事物都是虚拟的,电脑的设计初衷就是将现实事物虚拟在计算机的世界内,就好比我们人类的大脑,人类之所以能回忆以前美好的时光,那是因为大脑把人类那段美好的时光给记忆了,只有当你去回忆它,大脑就把存储这段信息给想想出来,对于计算机来说,同样也有个设备能够存储某些信息,而这个设备就是电脑的硬盘,而人类存储记忆的媒介就是我们的大脑。

学习教程 —— 使用浏览器客户端开发学习 JavaScript 基础(一)_第1张图片

以五行元素方式作参考,小图钉是铁属金类,小纸屑是纸属木类,你的口水数水类,对应编程语言中的字面量也是可以按类分的,只是编程语言是运行在计算机内,计算机是机器,只能接收电源输入的电,只能收集信息,不能接收小图钉呀、小纸屑呀和你的口水等等。

与其他编程语言不同,JavaScript 中有两大数据类型:基本数据类型、引用数据类型。

从上图可以看出栈内存类似于日常快递柜子,对于取快递我们是按快递编号取出来的,但栈内存有所不同的是,它是按照先进后出,后进先出的方式取值,有点不符合日常逻辑,按道理日常生活中,要么按序排队,要么插队处理,栈内存相当于羽毛球盒子,空盒子时,一个一个羽毛球放进去,但取羽毛球却是把最后一个先取出使用;而堆内存,按字理解就是一堆一堆的内存集合,这个内存集合也是有映射规则的,取堆内存就需要一个地址去指向对应的内存集合。

JavaScript 中并没有严格意义上区分栈内存和堆内存,可以理解为 JavaScript 是所有数据都保存在堆栈内存中,但有些场景,数据是特殊的对象模式,不能直接操作对象的堆内存空间,需要使用一个地址来关联引用对象,因此方位堆内存中的引用数据类型时,首先是从变量对象中获取了该对象的地址引用(地址指针),然后再从堆内存中获取需要的数据,常量放在常量池中,总结:基本数据类型对应的是值,引用数据类型对应的是地址

经典面试题目:一 使用中间变量,交换两个数值变量的值;二 不使用中间变量,交换两个数值变量的值
var num1 = 6, num2 = 8, temp;
--------------------------------------------------------------------------------------------------------------------------------
temp = num1;			// num1 = 6, num2 = 8, temp = 6
num1 = num2; 			// num1 = 8, num2 = 8, temp = 6
num2 = temp;			// num1 = 8, num2 = 6, temp = 6 从而实现了 num1 与 num2 两个变量的值交换
--------------------------------------------------------------------------------------------------------------------------------
num1 = num1 + num2;		// num1 = 14, num2 = 8
num2 = num1 - num2;		// num1 = 14, num2 = 6,第二个 num2 等价于上面的 num2 = 8
num1 = num1 - num2;		// num1 = 8, num2 = 6,第二个 num2 等价于上面的结果 num2 = 6

PS:在 ES 6 之前并没有声明常量的方法,在 ES 6+ 中新增使用 const 来声明常量,常量的值是不能被改变的,常量的值存储在常量池中

进制数值

在计算机的语言内只认知 0 和 1,这属于计算机最底层知识,一个数字占一个字节,一个字节等于 8 位,每四个为 1 位,转化位十进制数从右往左表示 2 的第几位减 1 次幂,多位就相加计算结果,JavaScript 中存在:二进制、八进制、十进制、十六进制

0 = 0000 0000 0000 0000 0000 0000 0000 0000				-- 从右往左算
1 = 0000 0000 0000 0000 0000 0000 0000 0001				--1 位取十进制表示 20 次幂(20 次方 = 12 = 0000 0000 0000 0000 0000 0000 0000 0010				--2 位取十进制表示 21 次幂(21 次方 = 23 = 0000 0000 0000 0000 0000 0000 0000 0011				-- 两位就相加 2 + 1 = 3
4 = 0000 0000 0000 0000 0000 0000 0000 0100				--3 位取十进制表示 22 次幂(22 次方 = 45 = 0000 0000 0000 0000 0000 0000 0000 0101				-- 两位就相加 4 + 1 = 5
  • 二进制数据:用 0 和 1 两个数码来表示的数,它的基数为 2,进位规则是 “逢二进一”,借位规则是 “借一当二”
  • 八进制数据:用 0~7 八个数码来表示的数,它的基数为 8,进位规则是 “逢八进一”,借位规则是 “借一当八”
  • 十进制数据:用 0~9 十个数码来表示的数,它的基数为 10,进位规则是 “逢十进一”,借位规则是 “借一当十”
  • 十六进制数据:用 0~9 和 a~f 十六个数码来表示的数,它的基数为 16,进位规则是 “逢十六进一”,借位规则是 “借一当十六”
十进制 二进制 八进制 十六进制
0 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
1 0000 0000 0000 0000 0000 0000 0000 0001 0000 0000 0000 0000 0000 0000 0000 0001 0000 0000 0000 0000 0000 0000 0000 0001
2 0000 0000 0000 0000 0000 0000 0000 0010 0000 0000 0000 0000 0000 0000 0000 0002 0000 0000 0000 0000 0000 0000 0000 0002
3 0000 0000 0000 0000 0000 0000 0000 0011 0000 0000 0000 0000 0000 0000 0000 0003 0000 0000 0000 0000 0000 0000 0000 0003
4 0000 0000 0000 0000 0000 0000 0000 0100 0000 0000 0000 0000 0000 0000 0000 0004 0000 0000 0000 0000 0000 0000 0000 0004
5 0000 0000 0000 0000 0000 0000 0000 0101 0000 0000 0000 0000 0000 0000 0000 0005 0000 0000 0000 0000 0000 0000 0000 0005
6 0000 0000 0000 0000 0000 0000 0000 0110 0000 0000 0000 0000 0000 0000 0000 0006 0000 0000 0000 0000 0000 0000 0000 0006
7 0000 0000 0000 0000 0000 0000 0000 0111 0000 0000 0000 0000 0000 0000 0000 0007 0000 0000 0000 0000 0000 0000 0000 0007
8 0000 0000 0000 0000 0000 0000 0000 1000 0000 0000 0000 0000 0000 0000 0000 0010 0000 0000 0000 0000 0000 0000 0000 0008
9 0000 0000 0000 0000 0000 0000 0000 1001 0000 0000 0000 0000 0000 0000 0000 0011 0000 0000 0000 0000 0000 0000 0000 0009
10 0000 0000 0000 0000 0000 0000 0000 1010 0000 0000 0000 0000 0000 0000 0000 0012 0000 0000 0000 0000 0000 0000 0000 000a
11 0000 0000 0000 0000 0000 0000 0000 1011 0000 0000 0000 0000 0000 0000 0000 0013 0000 0000 0000 0000 0000 0000 0000 000b
12 0000 0000 0000 0000 0000 0000 0000 1100 0000 0000 0000 0000 0000 0000 0000 0014 0000 0000 0000 0000 0000 0000 0000 000c
13 0000 0000 0000 0000 0000 0000 0000 1101 0000 0000 0000 0000 0000 0000 0000 0015 0000 0000 0000 0000 0000 0000 0000 000d
14 0000 0000 0000 0000 0000 0000 0000 1110 0000 0000 0000 0000 0000 0000 0000 0016 0000 0000 0000 0000 0000 0000 0000 000e
15 0000 0000 0000 0000 0000 0000 0000 1111 0000 0000 0000 0000 0000 0000 0000 0017 0000 0000 0000 0000 0000 0000 0000 000f
16 0000 0000 0000 0000 0000 0000 0001 0000 0000 0000 0000 0000 0000 0000 0000 0020 0000 0000 0000 0000 0000 0000 0000 0010

二进制数转十进制数,从右往左表示 2 的第几位减 1 次幂,多位就相加计算结果,以 0b 或 0B 前缀修饰
八进制数转十进制数,从右往左表示 8 的第几位减 1 次幂,多位就相加计算结果,以 0o 或 0O 前缀修饰
十六进制数转十进制数,从右往左表示 16 的第几位减 1 次幂,多位就相加计算结果,以 0x 或 0X 前缀修饰

0b11 = 1 * 22 - 1 次幂 + 1 * 21 - 1 次幂 = 1 * 21 次幂 + 1 * 20 次幂 = 1 * 2 + 1 * 1 = 2 + 1 = 3
0o35 = 3 * 82 - 1 次幂 + 5 * 81 - 1 次幂 = 3 * 81 次幂 + 5 * 80 次幂 = 3 * 8 + 5 * 1 = 24 + 5 = 29
0x1b = 1 * 162 - 1 次幂 + b(11) * 161 - 1 次幂 = 1 * 161 次幂 + b(11) * 160 次幂 = 1 * 16 + 11 * 1 = 16 + 11 = 27

十进制数转二进制数一直求余 2 到商为 0 位置,从右到左组合余数,越右边位数越高
十进制数转八进制数一直求余 8 到商为 0 位置,从右到左组合余数,越右边位数越高
十进制数转十六进制数一直求余 16 到商为 0 位置,从右到左组合余数,越右边位数越高

结果取值是从右到左的方式将取余值拼接而成
--------------------------------------------------------------------------------------------------------------------------------
23 = 23 % 2 = 11111 % 2 = 515 % 2 = 212 % 2 = 101 % 2 = 01  ---0b10111
23 = 23 % 8 = 272 % 8 = 02  ---0o27
23 = 23 % 16 = 171 % 16 = 01 ---0x17

数据类型

数据是值所有能输入到计算机并被计算机程序处理的符号的介质总称,是具有一定意义的数字、字母、符号和模拟量等的通称。

  • 基本类型:String 字符串、Number 数值、Boolean 布尔、Undefined、Null、Symbol(ES 6 新增)
    • 数值类型:包含整数和小数(例如:2、3.14 和 NaN)
    • 字符类型:字符组成的文本(例如:‘Hello’、“Hi”、`you`【ES 6 模板字符串】)
    • 布尔类型:true(真)和 false(假)两个特定值
    • 未定义型:表示未定义或不存在,此处没值
    • 空值类型:表示空缺,此处有值,但为空的
    • 标识类型:是一种唯一标识符,可用作变量的唯一属性名,不能被改写或覆盖
  • 引用类型:Object 对象、Array 数组、Date 日期、Function 函数、Math 算术、RegExp 正则以及自定义对象
    • 对象类型:是一种特殊的数据,包含属性和方法,可以指所有的事和物
    • 数组对象:使用单独的变量名来存储一系列的值
    • 日期对象:用于处理日期和时间
    • 函数对象:是一组可以随时随地调用运行的程序体,是 JavaScript 核心的核心
    • 算术对象:用于执行一些常见的算术任务
    • 正则对象:用于检索变量的赋值是否符合校验规则
声明数值类型:var inum = 12, fnum = 2.2, _num = -6;
声明字符类型:var dstr = 'hi', sstr = "tom", fstr = `jim age is ${
       inum}`;				// fstr = jim age is 12
声明布尔类型:var zbool = true, jbool = false;
声明控制类型:var wdyz = underfined, kzlx = null;
声明标识类型:var obj = {
      toString: function() {
      return 'hi'; }}, sym = Symbol(obj);	// sym = Symbol(hi)
--------------------------------------------------------------------------------------------------------------------------------
声明对象类型:var obj = {
      name: 'Tom', age: 5 };					// 对象属性值可以为任意的基本数据类型			
声明数组对象:var arr = [1, 2, 3, 4, 5, 6, 7, 8];					// 数组元素值可以为任意的基本数据类型
声明日期对象:var date = new Date();								// JavaScript 内置系统 Date 日期对象,用于处理日期时间
声明函数对象:var func = function() {
     };							// Function 函数代码块,方便其他地方复用
声明算术对象:var pi = Math.PI;									// JavaScript 内置系统 Math 算术对象,处理算术特别操作
声明正则对象:var reg = new RegExp("[0-9]", "igm");				// JavaScript 内置系统 RegExp 正则对象,用于检索变量取值规范

在《泰囧》电影中有这么一个场景,徐峥和王宝强一起在电梯内进来一个美女,他两窃窃私语讨论这个美女是人妖还是女性的场景,之后去百度了一下这个 Rose 这个演员曾经是泰国 “十大人妖皇后” 之一。在 JavaScript 中也有对应的方法来查看变量的数据类型

查看数据类型 可查看的数据类型
【typeof var-name】 “string”、“number”、“boolean”、“undefined”、“object”、“symbol” —— 返回值都是字符串
【v instanceof 引用类型】 “Object”、“Array”、“Date”、“RegExp”、“Function” —— 返回值都是布尔类型
【v.constructor === 引用类型】 “Object”、“Array”、“Date”、“RegExp”、“Function” —— 返回值都是布尔类型
【Object.prototype.toString.call(v)】 “[object String]”、"[object Number]"、"[object Boolean]"、"[object Undefined]"、"[object Null]"、"[object Symbol]"、"[object Function]"、"[object Object]"、"[object Array]"、"[object Date]"、"[object RegExp]"
var inum = 12, dstr = 'hi', zbool = true, kzlx = null, sbj = {
      toString: function() {
      return 'hi'; }}, sym = Symbol(obj),
	obj = {
      name: 'Tom', age: 5 }, arr = [1, 2, 3, 4, 5, 6, 7, 8], date = new Date(), func = function() {
     }, 
	pi = Math.PI, reg = new RegExp("[0-9]", "igm");
--------------------------------------------------------------------------------------------------------------------------------
console.log(typeof inum);								// "number"
console.log(typeof dstr);								// "string"
console.log(typeof zbool);								// "boolean"
console.log(typeof kzlx);								// "object"
console.log(typeof sym);								// "symbol"
console.log(typeof pi);									// "number"
console.log(obj instanceof Object);						// true
console.log(arr instanceof Array);						// true
console.log(date instanceof Date);						// true
console.log(func instanceof Function);					// true
console.log(reg instanceof RegExp);						// true
-------------------------------------------------------------------------------
console.log(obj.constructor === "Object");				// true
console.log(arr.constructor === "Array");				// true
console.log(date.constructor === "Date");				// true
console.log(func.constructor === "Function");			// true
console.log(reg.constructor === "RegExp");				// true
-------------------------------------------------------------------------------
console.log(Object.prototype.toString.call(obj));		// "[object Object]"
console.log(Object.prototype.toString.call(arr));		// "[object Array]"
console.log(Object.prototype.toString.call(date));		// "[object Date]"
console.log(Object.prototype.toString.call(func));		// "[object Function]"
console.log(Object.prototype.toString.call(reg));		// "[object RegExp]"
经典面试题目:var zbool = true; console.log(typeof typeof zbool); 输出的结果是什么?
通过 zbool = true 可以得出 zbool 是一个布尔类型,那么 typeof zbool 输出 "boolean",再进行 typeof "boolean" 字面量的判断为:"String"

保留关键字

关键字
abstract boolean break byte case catch char class const continue
debugger default delete do double else enum export extends final
finally float for function goto if implements import in instanceof
int interface long native new package private protected public return
short static super switch synchronized this throw throws transient try
typeof var void volatile while with

PS:保留关键字不能用作变量或函数的命名,使用关键字容易导致程序解析错误,会执行保留关键字的动作

命名规则

  • 推荐使用英文单词或单词简写命名,增加名称可读性
  • 不能使用除了下划线 (_) 和美元 ($) 符号外的任何符号
  • 可以使用字符或下划线和美元符号开头,不能使用数字开头,数字使用尽量少一些
  • 不能使用保留关键字命名,多个单词组合使用小驼峰法(即除第一个单词外所有代词首字母大写)
  • 常量的命名推荐使用大写字母拼写,如果存在多个单词使用下划线连接

布尔类型

  • 任何非零的整数都是 true,包括正负无穷大,只有 0 和 NaN 是 false,且 true == 1,false == 0
  • 任何非空的字符都是 true,只有空字符串和 ‘0’ 是 false
  • 任何对象都是 true,只有空数组是 false,另外由于 null 与 undefined 属对象,!!null === !!undefined === false
  • 另外 null == undefined、!!null == 0 == ‘0’ == ‘’ == ’ ’ == []、!!undefined == 0 == ‘0’ == ‘’ == ’ ’ == [] 也是成立的
布尔属性 属性描述
constructor 返回对创建此对象的 Boolean 函数的引用
prototype 使您有能力向对象添加属性和方法
布尔方法 方法描述
toString() 把布尔值转换为字符串,并返回结果
valueOf() 返回 Boolean 对象的原始值
Boolean.constructor;								// Function() { [native code] }
Boolean.prototype;									// 返回 Boolean 原型属性和方法
var bool = new Boolean(1); bool.toString();			// "true"
var bool = new Boolean(0); bool.valueOf();			// false

数值类型

  • 任何数字与 NaN 计算结果都是 NaN,任何布尔类型与 NaN 计算结果都是 NaN
数值属性 属性描述
constructor 返回对创建此对象的 Number 函数的引用
MAX_VALUE 可表示的最大的数
MIN_VALUE 可表示的最小的数
NEGATIVE_INFINITY 负无穷大,溢出时返回该值
NaN 非数字值
POSITIVE_INFINITY 正无穷大,溢出时返回该值
prototype 允许您可以向对象添加属性和方法
EPSILON (ES6+) 表示 1 和比最接近 1 且大于 1 的最小 Number 之间的差别
MIN_SAFE_INTEGER (ES6+) 表示在 JavaScript中最小的安全的 integer 型数字 (-(253 - 1))
MAX_SAFE_INTEGER (ES6+) 表示在 JavaScript 中最大的安全整数 (253 - 1)
Number.constructor;									// Function() { [native code] }
Number.MAX_VALUE;									// 1.7976931348623157e+308
Number.MIN_VALUE;									// 5e-324
Number.NEGATIVE_INFINITY;							// -Infinity
Number.POSITIVE_INFINITY;							// Infinity
Number.NaN;											// NaN
Number.prototype;									// 返回 Number 原型属性和方法
Number.EPSILON;										// 2.220446049250313e-16
Number.MIN_SAFE_INTEGER;							// -9007199254740991
Number.MAX_SAFE_INTEGER;							// 9007199254740991
数值方法 方法描述
isFinite(x) 检测指定参数是否为无穷大,为 true 表示有效,为 false 表示无穷大
toExponential(x) 把对象的值转换为指数计数法
toFixed(x) 把数字转换为字符串,结果的小数点后有指定位数的数字
toPrecision(x) 把数字格式化为指定的长度
toString() 把数字转换为字符串,使用指定的基数
valueOf() 返回一个 Number 对象的基本数字值
isInteger() (ES6+) 用来判断给定的参数是否为整数,返回 true 表示为整数,返回 false 表示非整数
isSafeInteger() (ES6+) 判断传入的参数值是否是一个"安全整数",返回 true 表示为安全整数,返回 false 表示非安全整数
Number.isFinite(123);									// true
Number.isFinite(-123);									// true
Number.isFinite('123');									// false
Number.isFinite(Infinity);								// false
Number.isFinite(-Infinity);								// false
Number.isFinite(5 - 2);									// true
Number.isFinite(0 / 0);									// false
var num = 5.56789; num.toExponential();					// "5.56789e+0"
var num = 5.56789; num.toFixed(2);						// "5.57"
var num = new Number(5.56789); num.toPrecision(2);		// "5.6"
var num = 5.56789; num.toString();						// "5.56789"
var num = 5.56789; num.valueOf();						// 5.56789
Number.isInteger(10);									// true
Number.isInteger(10.5);									// false
Number.isSafeInteger(10);								// true
Number.isSafeInteger(12345678901234567890);				// false

字符类型

  • 只有数字字符类型遇到转正转负,都会将字符型隐式自动转换未数值类型
  • 任何非数字字符数据遇到转正转负,结果都为 NaN,任何数字字符作计算时,都为对应数字
字符属性 属性描述
constructor 对创建该对象的函数的引用
length 字符串的长度
prototype 允许您向对象添加属性和方法
String.constructor;									// Function() { [native code] }
var s = '123'; s.length;							// 3
String.prototype;									// 返回 String 原型属性和方法
字符方法 方法描述
charAt() 返回在指定位置的字符
charCodeAt() 返回在指定的位置的字符的 Unicode 编码
concat() 连接两个或更多字符串,并返回新的字符串
fromCharCode() 将 Unicode 编码转为字符
indexOf() 返回某个指定的字符串值在字符串中首次出现的位置
includes() 查找字符串中是否包含指定的子字符串
lastIndexOf() 从后向前搜索字符串,并从起始位置(0)开始计算返回字符串最后出现的位置
match() 查找找到一个或多个正则表达式的匹配
repeat() 复制字符串指定次数,并将它们连接在一起返回
replace() 在字符串中查找匹配的子串, 并替换与正则表达式匹配的子串
search() 查找与正则表达式相匹配的值
slice() 提取字符串的片断,并在新的字符串中返回被提取的部分
split() 把字符串分割为字符串数组
startsWith() 查看字符串是否以指定的子字符串开头
substr() 从起始索引号提取字符串中指定数目的字符
substring() 提取字符串中两个指定的索引号之间的字符
toLowerCase() 把字符串转换为小写
toUpperCase() 把字符串转换为大写
trim() 去除字符串两边的空白
toLocaleLowerCase() 根据本地主机的语言环境把字符串转换为小写
toLocaleUpperCase() 根据本地主机的语言环境把字符串转换为大写
valueOf() 返回某个字符串对象的原始值
toString() 返回一个字符串
var str = "Hello World"; str.charAt(2);						// "l"
var str = "Hello World"; str.charCodeAt(0);					// 72
var s1 = "Hello ", s2 = "world!"; s1.concat(s2);			// "Hello world!"
var num = 65; String.fromCharCode(num);						// "A"
var str = "Hello World"; str.indexOf('wo');					// -1 (区分大小写)
var str = "Hello World"; str.lastIndexOf('l');				// 9
var str = "Hello World"; str.match(/llo/g);					// ["llo"]
var str = "Hello World"; str.replace("Hello","Hi");			// "Hi World"
var str = "Hello World"; str.search("Hello");				// 0
var str = "Hello World"; str.slice(1,5);					// "ello"
var str="a b c d e"; str.split(" ");						// ["a", "b", "c", "d", "e"]
var str = "Hello World"; str.substr(2,3);					// "llo"
var str = "Hello World"; str.substring(3);					// "lo World"
var str = "Hello World"; str.substring(3,7);				// "lo W"
var str = "Hello World"; str.toLowerCase();					// "hello world"
var str = "Hello World"; str.toUpperCase();					// "HELLO WORLD"
var str = "  Hello World  "; str.trim();					// "Hello World"
var str = "Hello World"; str.valueOf();						// "Hello World"
HTML 封装方法 HTML 封装方法描述 HTML 封装方法 HTML 封装方法描述
anchor() 创建 HTML 锚 italics() 使用斜体显示字符串
big() 用大号字体显示字符串 link() 将字符串显示为链接
blink() 显示闪动字符串 small() 使用小字号来显示字符串
bold() 使用粗体显示字符串 strike() 用于显示加删除线的字符串
fixed() 以打字机文本显示字符串 sub() 把字符串显示为下标
fontcolor() 使用指定的颜色来显示字符串 sup() 把字符串显示为上标
fontsize() 使用指定的尺寸来显示字符串

转义字符

代码 输出 代码 输出 代码 输出
\’ 单引号 \\ 反斜杠 \t 制表符
\" 双引号 \n 换行符 \b 退格符
\& 和号 \r 回车符 \f 换页符

类型转换

  • 非字符类型数据通过调用 .toString() 转换为字符串类型数据,也有部分因连接符自动转换字符串类型
  • 非数值类型数据通过调用 Number(x) 转换为数值类型数据,空字符、空格字符、false、null、[] 转数字为 0,true 转数字为 1,{} 转数字为 NaN
  • 非布尔类型数据通过调用 Boolean(x) 转换为布尔类型数据,’’、0、NaN、null、undefined 转布尔为 false,其他为 true
  • 通过 parseInt(x, v) 和 parseFloat(x) 提取有效整数和浮点数,其中 parseInt 第二个参数表示 x 为几进制数据
  • 整数数据转浮点数精度不会丢失,反过来浮点数转换为整数数据精度会丢失
var num = 123; num.toString();						// "123"
var num = NaN; num.toString();						// "NaN"
var bool = true; bool.toString();					// "true"
var onul = String(null); onul.toString();			// "null"
var oudf = String(undefined); oudf.toString();		// "undefined"
var arr = [1,2,3]; arr.toString();					// "1,2,3"
var obj = {
     a:1,b:'12'}; obj.toString();				// "[object Object]"
var num = 12; num + 'ab';							// "12ab"
var bool = true; bool + 'ab';						// "trueab"
var onul = String(null); onul + 'ab';				// "nullab"
var oudf = String(undefined); oudf + 'ab';			// "undefinedab"
var arr = [1,2,3]; arr + 'ab';						// "1,2,3ab"
var obj = {
     a:1,b:'12'}; obj + 'ab';					// "[object Object]ab"

var str = '123'; Number(str);						// 123
var str = '123'; +str;								// 123 (取正取负也可以将字符串转换为数值类型数据)
var str = '123ab'; Number(str);						// NaN
var str = 'ab123'; Number(str);						// NaN
var str = ''; Number(str);							// 0
var str = ' '; Number(str);							// 0
var bool = true; Number(bool);						// 1
var bool = false; Number(bool);						// 0
true + true;										// 2 
true + false;										// 1
true + 2;											// 3
var onul = null; Number(onul);						// 0
var oudf = undefined; Number(oudf);					// NaN
var arr = []; Number(arr);							// 0
var obj = {
     }; Number(obj);							// NaN

var str = '123'; Boolean(str);						// true
var str = ''; Boolean(str);							// false
var str = ' '; Boolean(str);						// true
var str = '0'; Boolean(str);						// true
var num = 12; Boolean(num);							// true
var num = 0; Boolean(num);							// false
var num = NaN; Boolean(num);						// false
var onul = null; Boolean(onul);						// false
var oudf = undefined; Boolean(oudf);				// false
var arr = []; Boolean(arr);							// true
var obj = {
     }; Boolean(obj);							// true

var str = '123'; parseInt(str, 8);					// 83
var str = '123'; parseInt(str, 16);					// 291
var str = '11'; parseInt(str, 2);					// 3
var str = '11.00'; parseFloat(str);					// 11
var str = '11.01'; parseFloat(str);					// 11.01
var n1 = 5, n2 = 3; n1 / n2;						// 1.6666666666666667
var nf = 1.6666666666666667; parseInt(nf);			// 1
--------------------------------------------------------------------------------------------------------------------------------
经典面试题目:判断 console.log('a' + + 'b'); 的输出结果
非数字字符转正转负为 NaN,那么 +'b' = NaN,那么 'a' + NaN = "aNaN"

经典面试题目:判断 console.log(1 + +'2' + '2');、console.log(1 + +'A' + '2');、console.log(1 + +'A' + 2); 分别输出结果
1. 数字字符转正转负为对应数字,那么 +'2' = 2,先执行 1 + 2 = 3,再执行 3 + '2' = "32"
2. 非数字字符转正转负为 NaN,那么 +'A' = NaNNaN 与任何数字计算都等于 NaN,即 1 + NaN = NaN,再执行 NaN + '2' = "NaN2"
3. 非数字字符转正转负为 NaN,那么 +'A' = NaNNaN 与任何数字计算都等于 NaN,即 1 + NaN = NaN,再执行 NaN + 2 = NaN

经典面试题目:判断 var a = '999', b = '9'; 求 console.log(a % b) 的结果
任何数字字符作计算时,都为对应数字,那么 a = 999,b = 9,即 999 % 9 求余为 0

经典面试题目:判断 var a = '999', b = 'a'; 求 console.log(a % b) 的结果
任何数字字符作计算时,都为对应数字,任何非数字作计算时,都为 NaN,那么 a = 999,b = NaN,任何数与 NaN 作计算结果都为 NaN,即 999 % NaN 求余为 NaN

ASCII 码

字符 字符 字符 字符 字符 字符 字符 字符 字符 字符
0 NUT 13 CR 26 SUB 39 , 52 4 65 A 78 N 91 [ 104 h 117 u
1 SOH 14 SO 27 ESC 40 ( 53 5 66 B 79 O 92 / 105 i 118 v
2 STX 15 SI 28 FS 41 ) 54 6 67 C 80 P 93 ] 106 j 119 w
3 ETX 16 DLE 29 GS 42 * 55 7 68 D 81 Q 94 ^ 107 k 120 x
4 EOT 17 DCI 30 RS 43 + 56 8 69 E 82 R 95 _ 108 l 121 y
5 NEQ 18 DC2 31 US 44 , 57 9 70 F 83 S 96 ` 109 m 122 z
6 ACK 19 DC3 32 (space) 45 - 58 : 71 G 84 T 97 a 110 n 123 {
7 BEL 20 DC4 33 ! 46 . 59 ; 72 H 85 U 98 b 111 o 124 |
8 BS 21 NAK 34 " 47 / 60 < 73 I 86 V 99 c 112 p 125 }
9 HT 22 SYN 35 # 48 0 61 = 74 J 87 W 100 d 113 q 126 `
10 LF 23 TB 36 $ 49 1 62 > 75 K 88 X 101 e 114 r 127 DEL
11 VT 24 CAN 37 % 50 2 63 ? 76 L 89 Y 102 f 115 s
12 FF 25 EM 38 & 51 3 64 @ 77 M 90 Z 103 g 116 t

变量操作

JavaScript 运算符
算术运算符
关系运算符
逻辑运算符
拼接运算符
赋值运算符
位运算符
自增自减
三目运算
  • 算术运算符:加 ‘+’、减 ‘-’、乘 ‘*’、除 ‘/’、取模 ‘%’
  • 关系运算符:大于 ‘>’、小于 ‘<’、等于 ‘==’、全等 ‘===’、大于等于 ‘>=’、小于等于 ‘<=’、不等于 ‘!=’、全不等 ‘!==
    • 结果值:比较运算符左右两边判断的结果,返回一个布尔类型数据:true 或 false
    • 全等于:表示两边的值和类型都相等,例:‘0’ == 0,‘0’ !== 0 (值相等,但类型不等),NaN != NaN
    • 字符串:关系运算符不会将字符类型数据进行直接比较,而是将字符类型数据转换为 Unicode 编码后再比较
  • 逻辑运算符:与 ‘&&’、或 ‘||’、非 ‘!’,与:一假即假,或:一真即真,非:真为假,假为真
    • 注意点:针对非布尔类型的表达式会自动转换位布尔类型,推荐使用两个逻辑非 !! 去处理非布尔类型数据
    • 与短路:只要与 ‘&&’ 前面是 false,无论与 ‘&&’ 后面是 true 或 false,结果返回与 ‘&&’ 前面的值,否则返回后面的值
    • 或短路:只要或 ‘||’ 前面是 false,无论或 ‘||’ 后面是 true 或 false,结果返回或 ‘||’ 后面的值,否则返回前面的值
  • 拼接运算符:拼接 ‘+’,条件 ‘?:’
    • 拼接结果:将非字符类型数据自动转换为字符类型后进行拼接,返回一个拼接后的字符类型数据
    • 三目运算:判断表达式是否成立,成立执行问号 ‘?’ 后面程序,否则执行冒号 ‘:’ 后面程序
  • 赋值运算符:赋值 ‘=’、加后赋值 ‘+=’、减后赋值 ‘-=’、乘后赋值 ‘*=’、除后赋值 ‘/=’、取模赋值 ‘%=’
  • 位 运 算 符:按位与 ‘&’、按位或 ‘|’、按位非 ‘~’、按位异或 ‘^’、有符号左移 ‘<<’、有符号右移 ‘>>’、无符号右移 ‘>>>’
  • 自增自减:++ 加加、-- 减减、- 取负
    • ++ 加加、-- 减减在后面混合运算,先执行运算,后变量执行++ 加加、-- 减减
    • ++ 加加、-- 减减在前面混合运算,先变量执行++ 加加、-- 减减,后执行运算
var a = 1, b = 2; a + b;									// 3
var a = 100.1, b = 2.1; a + b;								// 102.19999999999999 (浮点数会丢失精度)
var a = 1, b = 2; a - b;									// -1
var a = 2, b = 2; a * b;									// 4
var a = 2, b = 2; a / b;									// 1
var a = 5, b = 2; a % b;									// -1
var a = 1, b = 2; a > b;									// false
var a = 1, b = 2; a < b;									// false
var a = 1, b = '1'; a == b;									// true
var a = 1, b = '1'; a === b;								// false
var a = 1, b = 2; a >= b;									// false
var a = 1, b = 2; a <= b;									// false
var a = 1, b = '1'; a != b;									// false
var a = 1, b = '1'; a !== b;								// true
var a = 1, b = 2, c = 3, d = 4; a > b && c > d;				// false
var a = 1, b = 2, c = 3, d = 4; a > b || c > d;				// true
var a = 1, b = 2; !(a > b);									// true
var a = 1, b = '1'; a + b;									// 12
var a = 1, b = 2; a > b ? a : b;							// 2
var a = 2, b = 4, c = 6, d = 8, e = 10, f = 12; a;b;c;d;e;f;// 2 4 6 8 10 12
b += 1; b;													// 5
c -= 2; c;													// 4
d *= 3; d;													// 24
e /= 4;	e;													// 2
f %= 5; f;													// 2
var a = 3, b = 1; a & b;									// 1
--------------------------------------------------------------------------------------------------------------------------------
  0000 0000 0000 0000 0000 0000 0000 0011
  0000 0000 0000 0000 0000 0000 0000 0001
  --------------------------------------- 一假即假
& 0000 0000 0000 0000 0000 0000 0000 0001

var a = 3, b = 1; a | b;									// 3
--------------------------------------------------------------------------------------------------------------------------------
  0000 0000 0000 0000 0000 0000 0000 0011
  0000 0000 0000 0000 0000 0000 0000 0001
  --------------------------------------- 一真即真
& 0000 0000 0000 0000 0000 0000 0000 0011

var a = 3; ~a;												// -4
--------------------------------------------------------------------------------------------------------------------------------
  0000 0000 0000 0000 0000 0000 0000 0011
  ----------------------------------------- 取反
  1111 1111 1111 1111 1111 1111 1111 1100
  ----------------------------------------- 最高位为1代表负数不变,其他位取反
  1000 0000 0000 0000 0000 0000 0000 0011
  +									    1
  -----------------------------------------1
  1000 0000 0000 0000 0000 0000 0000 0100 = -4
  
var a = 3, b = 1; a ^ b;									// 2
--------------------------------------------------------------------------------------------------------------------------------
  0000 0000 0000 0000 0000 0000 0000 0011
  0000 0000 0000 0000 0000 0000 0000 0001
  --------------------------------------- 正负为真,负负得负,正正得负
^ 0000 0000 0000 0000 0000 0000 0000 0010

var a = 3, b = 1; a << b;									// 6
--------------------------------------------------------------------------------------------------------------------------------
  0000 0000 0000 0000 0000 0000 0000 0011
  ----------------------------------------- 左移 10000 0000 0000 0000 0000 0000 0000 0011
  ----------------------------------------- 去掉左边多出的,右边补0
  0000 0000 0000 0000 0000 0000 0000 0110

var a = 3, b = 1; a >> b;									// 1
--------------------------------------------------------------------------------------------------------------------------------
  0000 0000 0000 0000 0000 0000 0000 0011
  ----------------------------------------- 右移 10000 0000 0000 0000 0000 0000 0000 0011
  ----------------------------------------- 去掉右边多余的,左边补0
  0000 0000 0000 0000 0000 0000 0000 0001
  
var a = -64, b = 5; a >> b;									// -2
--------------------------------------------------------------------------------------------------------------------------------
  1000 0000 0000 0000 0000 0000 0100 0000
  ----------------------------------------- 除掉第一位右移 51      000 0000 0000 0000 0000 0000 0100 0000
  ----------------------------------------- 去掉右边多余的,中间补0
  1000 0000 0000 0000 0000 0000 0000 0010	-2
  
var a = 5, b = 2; a >>> b;									// 1
--------------------------------------------------------------------------------------------------------------------------------
  0000 0000 0000 0000 0000 0000 0000 0101
  ----------------------------------------- 右移 20000 0000 0000 0000 0000 0000 0000 0101
  ----------------------------------------- 去掉右边多余的,左边补0
  0000 0000 0000 0000 0000 0000 0000 0001
  
var a = 5, b = 1; a >>> b;									// 2
--------------------------------------------------------------------------------------------------------------------------------
  0000 0000 0000 0000 0000 0000 0000 0101
  ----------------------------------------- 右移 20000 0000 0000 0000 0000 0000 0000 0101
  ----------------------------------------- 去掉右边多余的,左边补0
  0000 0000 0000 0000 0000 0000 0000 0010

var a = -64, b = 5; a >>> b;								// 134217726
  0000 0000 0000 0000 0000 0000 0100 0000
  ----------------------------------------- 64 反码
  1111 1111 1111 1111 1111 1111 1011 1111
  +									    1
  -----------------------------------------1
  1111 1111 1111 1111 1111 1111 1100 0000
  -----------------------------------------  右移 51111 1111 1111 1111 1111 1111 1100 0000
  ----------------------------------------- 去掉右边多余的,左侧补0
  0000 0111 1111 1111 1111 1111 1111 1110					// 最高位为 0 表示为整数
  ----------------------------------------- 111111111111111111111111110 通过工具 https://tool.lu/hexconvert
  111111111111111111111111110 转化为 10 进制数 134217726
  
var a = -60, b = 5; a >>> b;								// 134217726
  0000 0000 0000 0000 0000 0000 0011 1100
  ----------------------------------------- 60 反码
  1111 1111 1111 1111 1111 1111 1100 0011
  +									    1
  -----------------------------------------1
  1111 1111 1111 1111 1111 1111 1100 0100
  -----------------------------------------  右移 51111 1111 1111 1111 1111 1111 1100 0100
  ----------------------------------------- 去掉右边多余的,左侧补0
  0000 0111 1111 1111 1111 1111 1111 1110
  
var a = -30, b = 2; a >>> b;								// 1073741816
  0000 0000 0000 0000 0000 0000 0001 1110
  ----------------------------------------- 20 反码
  1111 1111 1111 1111 1111 1111 1110 0001
  +									    1
  -----------------------------------------1
  1111 1111 1111 1111 1111 1111 1110 0010
  -----------------------------------------  右移 21111 1111 1111 1111 1111 1111 1110 0010
  ----------------------------------------- 去掉右边多余的,左侧补0
  0011 1111 1111 1111 1111 1111 1111 1000
  
var i = 0; i++;												// 1 (类似于 += 1)
var i = 0; i--;												// -1 (类似于 -= 1)
var i = 0; ++i;												// 1 (类似于 += 1)
var i = 0; --i;												// -1 (类似于 -= 1)
var i = 1; -i;												// -1
var a = 5, b = 4, r = (a++) + (b++);						// r = 9, a = 6, b = 5 (先计算后自增)
var a = 5, b = 4, r = (++a) + (++b);						// r = 11, a = 6, b = 5 (先自增后计算)
PS: 复制二进制结果数据到在线工具转换之前,需要把空格去掉,不然空格被视为 0
[] == [];													// false
[] == ![];													// true

运算优先

优先级(高到低) 运算符 运算符描述
1 []、.、() 数组下标、字段访问、函数调用以及表达式分组
2 ++、–、-、~、!、delete、new、typeof、void 自增、自减、取负、按位非、逻辑非、删除、实例、类型、空返
3 *、/、%、+、- 乘、除、取模、加、减
4 <<、>>、>>> 有符号左移、有符号右移、无符号右移
5 <、<=、>、>=、instanceof 小于、小于等于、大于、大于等于、类型
6 ==!====!== 相等、不等、全等、不全等
7 &、^、|、&&、||、?: 按位与、按位异或、按位或、逻辑与、逻辑或、条件运算
8 =、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=、>>>= 赋值、算术赋值、位运算赋值
9 , 多重求值

流程控制

代码块:由一组花括号包围的 JavaScript 程序语句,JavaScript 程序默认是按书写从上至下顺序执行的,但实际有些需求是根据不同的条件执行不同的代码块,为了方便控制程序的运行流程,JavaScript 提供了 3 种流程结构:顺序、选择、循环

  • 顺序结构:默认的流程结构,按照书写循序从上至下执行每一行语句
  • 选择结构:对给定的条件进行判断,在根据判断结果来决定执行哪一段代码
  • 循环结构:在给定条件成立的情况下,反复执行某一段代码
true
false
true
false
执行开始
代码块
条件
代码块
代码块
条件
代码块
程序结束
代码块
代码块
代码块
  • if 语句:条件判断成立就执行,否则不执行
  • if - else 语句:条件判断要么是这个,要么为那个
  • if - else if 语句:条件细分判断,但仅仅执行一个语句块
var score = 100;
if(100 == score) {
     	// 判断成绩是否满分
	console.log('本科成绩第一名')
}

var score = 88;		// 考试成绩高于 90 分有奖励,否则重新练习错误题
if(score >= 90) {
     
	console.log('奖励一本本子')
} else {
     
	console.log('重新练习错误提')
}

score >= 90 ? console.log('奖励一本本子') : console.log('重新练习错误提');

var score = 92;		// 根据成绩打印 ABCD
if(score >= 90) {
     
	console.log('成绩为:A');
} else if(score >= 75) {
     
	console.log('成绩为:B');
} else if(score >= 60) {
     
	console.log('成绩为:C');
} else {
     
	console.log('成绩为:D');
}

注意事项

  • 如果只有一条语句时,if 后面的大括号可以省略
  • 分号 “;” 也是一条语句,空语句
  • if - else 是一个整体,else 匹配 if 的时候,匹配离他最近的一个 if
  • 对于非 Boolean 类型的值,会先转换为 Boolean 类型后再判断
  • 判断变量与字面量问题,字面量在前,变量在后,防止表达式写成赋值运算
  • if 语句可以嵌套使用
分支一
分支二
分支三
分支四
分支五
分支六
分支七
分支八
分支九
分支十
执行开始
条件判断
语块一
语块二
语块三
语块四
语块五
语块六
语块七
语块八
语块九
语块十

计算条件表达式的值,并逐个与 CASE 后面字面量比较,当条件表达式的值与某个分支的字面量全等(值和类型)时,执行其后的语句,并且不会再与其他的 CASE 进行比较,如果条件表达式的值与所有的 CASE 后面的字面量均不全等,则执行 DEFAULT 后面的语句。

var week = '星期三';
switch(week) {
     
	case '星期日': console.log('好好休息!'); break;
	case '星期一': console.log('烹饪培训!'); break;
	case '星期二': console.log('电脑培训!'); break;
	case '星期三': console.log('朋友走访!'); break;
	case '星期四': console.log('前往北京!'); break;
	case '星期五': console.log('参观故宫!'); break;
	default: console.log('返回住所!'); break;
}

if('星期日' == week) {
     
	console.log('好好休息!');
} else if('星期一' == week) {
     
	console.log('烹饪培训!');
} else if('星期二' == week) {
     
	console.log('电脑培训!');
} else if('星期三' == week) {
     
	console.log('朋友走访!');
} else if('星期四' == week) {
     
	console.log('前往北京!');
} else if('星期五' == week) {
     
	console.log('参观故宫!');
} else {
     
	console.log('返回住所');
}

var now = new Date(), yY = now.getFullYear(), mM = now.getMonth() + 1;
switch(mM) {
     
	case 1: case 3: case 5: case 7: case 8: case 10: case 12: console.log('当月存在 31 天!'); break;
	case 4: case 6: case 9: case 11: console.log('当月存在 31 天!'); break;
	case 2:
    	if(yY % 4 == 0 && yY % 100 != 0 || yY % 400 == 0) {
     
    		console.log('当月存在 29 天!');
    	} else {
     
    		console.log('当月存在 28 天!');
    	}
	break;
}

var score = 92;		// 根据成绩打印 ABCDE
if(score >= 90) {
     
	console.log('成绩为:A');
} else if(score >= 80) {
     
	console.log('成绩为:B');
} else if(score >= 70) {
     
	console.log('成绩为:C');
} else if(score >= 60) {
     
	console.log('成绩为:D');
} else {
     
	console.log('成绩为:E');
}
switch(parseInt(score)) {
     		// 通过取整取匹配
	case 10: case 9: console.log('成绩为:A'); break;
	case 8: console.log('成绩为:B'); break;
	case 7: console.log('成绩为:C'); break;
	case 6: console.log('成绩为:D'); break;
	case 5: case 4: case 3: case 2: case 1: case 0: console.log('成绩为:E'); break;
}

分支语句与条件语句不同之处

  • 条件语句可判断范围条件,而分支语句只能判断固定等值
  • 分支语句条件通过 CASE 匹对,而条件语句通过 “==” 比较
  • 分支语句需要通过 BREAK 跳出,而条件语句默认执行一条后跳出
  • 分支语句表达式结果只能为数值、字符类型,条件语句不受限制
继续
开始
变量声明
进入循环
条件判断
循环体
退出循环
结束
  • while 循环:判断条件是否成立,成立则进入循环体,否则退出循环体
  • do-while 循环:先进入循环体执行一次,然后判断条件是否继续循环,成立继续,否则跳出循环体
  • for 循环:判断条件,成立执行固定次数的循环体
  • for-in 迭代:用于遍历对象的属性
  • break 语句:用于跳出循环体
  • continue 语句:用于跳过循环中的一个迭代
var num = 0, sum = 0;		
while(num < 100) {
     
	sum += ++num;
}
console.log('1+2+3+...+100=' + sum);

var num = 0, sum = 0;
while(1) {
     
	sum += ++num;
	if(num >= 100) {
     
		console.log('1+2+3+...+100=' + sum);
		break;
	}
}

var num = 0, sum = 0;
do {
     
	sum += ++num;
} while(num < 100);
console.log('1+2+3+...+100=' + sum);

for(var i = 0, sum = 0; i < 100; i++) {
     
	sum += 1 + i;
}
console.log('1+2+3+...+100=' + sum);

for(var i = 0, sum = 0; i < 100; i++) {
     
	if(i % 2 == 0) {
     
		continue;
	}
	sum += 1 + i;
}
console.log('1+3+5+...+99=' + sum);

for(var i = 1, res = ''; i <= 9; i++) {
     
	for(var j = 1; j <= i; j++) {
     
		var s = i * j;
		res += (j + ' * ' + i + ' = ' + (s > 9 ? s : ' ' + s) + '  ');
	}
	res += '\n';
}
console.log(res);
------------------------------------------------------------------------------------------------------------
1 * 1 =  1  
1 * 2 =  2  2 * 2 =  4  
1 * 3 =  3  2 * 3 =  6  3 * 3 =  9  
1 * 4 =  4  2 * 4 =  8  3 * 4 = 12  4 * 4 = 16  
1 * 5 =  5  2 * 5 = 10  3 * 5 = 15  4 * 5 = 20  5 * 5 = 25  
1 * 6 =  6  2 * 6 = 12  3 * 6 = 18  4 * 6 = 24  5 * 6 = 30  6 * 6 = 36  
1 * 7 =  7  2 * 7 = 14  3 * 7 = 21  4 * 7 = 28  5 * 7 = 35  6 * 7 = 42  7 * 7 = 49  
1 * 8 =  8  2 * 8 = 16  3 * 8 = 24  4 * 8 = 32  5 * 8 = 40  6 * 8 = 48  7 * 8 = 56  8 * 8 = 64  
1 * 9 =  9  2 * 9 = 18  3 * 9 = 27  4 * 9 = 36  5 * 9 = 45  6 * 9 = 54  7 * 9 = 63  8 * 9 = 72  9 * 9 = 81 

var obj = {
      name: 'Tom', sex: 'boy', age: 5 };
for(var key in obj) {
     
	console.log('the ' + key + ' is ' + obj[key]);
}
// the name is Tom
// VM206:3 the sex is boy
// VM206:3 the age is 5

三:内置对象

JavaScript 设计中内置了许多对象:Number、String、Boolean、Null、Undefined、Symbol、Object、Array、Date、Math、Function、RegExp、Error对象

对象声明

对象是一种特殊的引用数据类型,拥有属性和方法,JavaScript 中所有的事务都是对象:字符串、数值、数组、函数等

  • 使用对象实例化方式创建对象:var obj = new Object();
  • 使用对象字面量方式创建对象:var obj = {};
function say() {
     
	console.log('miao');
}
var obj = new Object();
obj.name = 'Tom';
obj.age  = 5;
obj.say = say;					// 需要通过 obj.say() 方法调用
obj.say = say();				// 需要通过 obj.say 方法调用

var obj = {
     
	name: 'Tom',
	age: 5,
	say: function() {
     			// 匿名函数
		console.log('miao');
	}
};

通过使用函数来构造对象,就可以通过创建对象实例

function person(name, sex, age) {
     
	this.name = name;
	this.sex = sex;
	this.age = age;
}
var tom = new person('Tom', 'boy', 12);
console.log(tom.name, tom.sex, tom.age);
var lily = new person('Lily', 'girl', 10);
console.log(lily.name, lily.sex, lily.age);

函数声明

函数是定义一次但却可以调用或执行任意多次的一段 JS 代码,函数有时会有参数,通过调用函数进行参数的传递,有些函数也会将函数体执行的结果返回出来,这个返回值也是函数调用表达式的值。

语法:function fun-name([args]) { 函数执行体; }

有、无参数函数

function message() {
     					// 经常使用采用这种模式声明
	console.log('hello world');
}
message();								// 函数本身是不执行的,只有被调用时才执行
var message = function() {
     				// 执行体系大,采用这种模式声明
	console.log('hello world');
}

function myAdd(a, b) {
     
	console.log('两个数的和为:' + (a + b));
}
myAdd(2, 3);							// 5

返回数据

函数通过 return 返回函数体执行的结果,在函数调用时返回,并赋值给一个变量,return 发生了执行,后续代码无意义,不执行

function message() {
     
	return 'hello world';
}
var msg = message();					// msg = 'hello world'

function myAdd(a, b) {
     
	return a + b;
}
var sum = myAdd(2, 3);					// sum = 5

形参实参

  • 形参:就是函数在声明定义的时候参数变量
  • 实参:就是函数在调用传值的时候传递数据

JavaScript 中函数的形参设置多少,实参个数可以与形参个数不同,是被允许的,arguments 为函数的形参对象,是一个伪数组

arguments 有一个指针函数 callee(),用于指向 arguments 所在的函数,参考下面:# 内部指针

function addNum() {
     
	for(var sum = 0, i = 0; i < arguments.length; i++) {
     
		sum += arguments[i];
	}
	return sum;
}
var sum = addNum(2,5, 5);			// sum = 12
var sum = addNum(12, 4);			// sum = 16

匿名闭包回调

  • 匿名函数:就是没有名字的函数,单独的匿名函数是没法自身运行和调用的,常用于赋值,也可通过表达式运行
  • 闭包函数:就是函数内返回的一个可访问当前函数作用域的内部函数体,驻留局部变量,避免使用全局变量
  • 回调函数:通过一个函数调用另外一个函数,回调函数通常作为一个函数的参数传递,等到这个函数执行完成之前,调用回调函数
function addNum(a, b) {
     }			// 普通函数
var addNum = function(a, b) {
     };		// 等号右侧就是一个匿名函数,通过 addNum()
(function(a, b) {
     })(a, b);			// 表达式调用匿名函数,JQuery 的封装就是一个表达式的匿名函数
// 把匿名函数执行结果赋值给变量,与上面不同,上面是把匿名函数赋值给变量,变量就成了 Function 引用类型
var addNum = (function(a, b) {
      return a + b; })(a, b);
--------------------------------------------------------------------------------------------------------------------------------
for (var i = 0; i < 5; i++) {
     
	setTimeout(function() {
      console.log(i); }, i * 1000 );
}
解析:上面的代码不会按预期显示值01234,而是会显示 55555,原因是:在循环中执行的每个函数将整个循环完成之后被执行,会导致计时器函数引用存储的最有一个 i = 5 的值,所以会输出:55555
for (var i = 0; i < 5; i++) {
     
    (function(x) {
     
        setTimeout(function() {
      console.log(x); }, x * 1000 );
    })(i);
}
--------------------------------------------------------------------------------------------------------------------------------
function cat(name, callback) {
     
	callback(name + 'see Jerry');
}
cat('Tom', function(message) {
      console.log(message); });			// "Tom see Jerry"

内存回收

在 JavaScript 定义的全局变量是不会被立即回收的,只有当关闭浏览器时,才会触发回收机制,垃圾不回收容易导致运行卡顿、内存溢出等现象,对于内存管理,是开发者必备的一块技术点,如何优化 JavaScript 的内存管理:

  • 善用函数,普通函数的创建,有时候会导致变量的提升,从而内存不会立即释放,推荐使用匿名函数方式
  • 使用普通函数,需要手动解除变量引用,重置为 null,从而减少内存占用,释放内存
  • 绝对不要定义全局变量,通过匿名函数传值发方式传递局部变量,也可以通过回调函数方式进行变量传值
for(var i = 0; i < 5; i++) {
     }
console.log(i);						// 5 不会被销毁
// 使用块模块封装,处理全局变量内存管理
(function() {
     
	for(var i = 0; i < 5; i++) {
     }
})();
console.log(i);						// Uncaught ReferenceError: i is not defined
--------------------------------------------------------------------------------------------------------------------------------
;(function(document, window){
     
	var btns = document.querySelectorAll('.btn');
	var output = document.querySelector('#output');
	var arrs = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
	for(var i = 0; i < btns.length; i++) {
     
		btns[i].onclick = (function(num){
     
			return function() {
     
				output.innerText += 'Clicked ' + num;
			};
		})(arrs[i]);
	}
})(document, window);

内部指针

  • arguments.callee() 返回正被执行的 Function 对象,常用于匿名函数的递归或者保证函数的封装性
  • this 默认指向 window(JavaScript 里面最大的对象,最外围的对象),可以指向当前对象或引用对象
  • apply() 用于设置 this 的指向,默认 this 指向 window,参数是那个对象,调用方法中的 this 就指向这个对象
function factorial(num) {
     									// 数的阶乘计算
	if (num <= 1) {
      return 1; } 
	return num * arguments.callee(num - 1);					// 会存在一个调用记录,每次调用就会形成一个调用栈
}
var res = factorial(3);										// !3 = 3 * 2 * 1 = 6
PS:不推荐使用 arguents.callee(),访问 arguments 是个很昂贵的操作,它是个很大的对象,每次递归调用时都需要重新创建,影响现代浏览器的性能,还会影响闭包,解决方法就是给内部函数指定一个名字,在条件满足是,尾调用这个函数
function factorial(num) {
     									// 数的阶乘计算
	return (function tailFactorial(num, total) {
     
		if(num === 1) return total;
		return tailFactorial(n - 1, n * total);				// 尾调用自己
	})(num, 1);
}
var res = factorial(3);										// !3 = 3 * 2 * 1 = 6
--------------------------------------------------------------------------------------------------------------------------------
function currying(fn) {
     
	return function(list) {
     
		return fn.call(this, list);							// 使用柯里化
	}
}
function recursion(list) {
     
	return (function tailRecursion(item, arr) {
     
		arr.push(item + 1);
		if(list.length === 0) return arr;
		return tailRecursion(list.splice(0,1)[0], arr)
	})(list.splice(0,1)[0], [])
}
var res = currying(recursion)([1, 2, 3, 4, 5]);				// res = [2, 3, 4, 5, 6]
--------------------------------------------------------------------------------------------------------------------------------
function recursion(list, arr = []) {
     						// ES 6 语法
	var item = list.splice(0,1)[0];
	arr.push(item + 1);
	if (list.length === 0) {
     
		return arr;
	}
	return recursion(list, arr);
}
var res = recursion([1, 2, 3, 4, 5]);
var color = 'red';
var car = {
     
	name: '大众',
	color: this.color							// this 指向 window:是 JavaScript 里面最大的对象,最外围的对象
};
--------------------------------------------------------------------------------------------------------------------------------
var car = {
     
	name: '大众',
	text: 'green',
	color: function() {
     
		return this.text;						// this 指向 car
	}
};
car.color();
--------------------------------------------------------------------------------------------------------------------------------
function person() {
     
	this.name = 'zhangsan';						// this 指向引用对象 person()
}
var zs = new person();
zs.name;										// 'zhangsan'
--------------------------------------------------------------------------------------------------------------------------------
function say() {
     
	console.log(this.text);						// this 指向引用对象 cat
}
var cat = {
     };
cat.text = 'miao';
cat.say = say;
cat.say();										// 'miao'
var person = {
     
	fullName: function() {
     
		return this.fName + ' ' + this.lName;	// 这里的 this 就对应到 apply 传入的对象
	}
};
var zs = {
     
	fName: 'zhang',
	lName: 'san'
};
person.fullName.apply(zs);						// zhang san
--------------------------------------------------------------------------------------------------------------------------------
function addNum1(a, b) {
     
	console.log(this);
	return a + b;
}
function addNum2(a, b) {
     
	return addNum1.apply(this, [a, b]);			// this 指向 window,apply 用于调用自身方法
}
addNum2(2, 3);
--------------------------------------------------------------------------------------------------------------------------------
function addNum1(a, b) {
     
	console.log(this);
	return a + b;
}
function addNum2(a, b) {
     
	return addNum1.call(this, a, b);			// this 指向 window,apply 用于调用自身方法
}
addNum2(2, 3);

变量作用域

JavaScript 内所有的函数的参数都是局部变量,没有引用传递方式

function message(text) {
     
	text = '改变';
}
var text = '原来';
message(text);									// text = '原来'
--------------------------------------------------------------------------------------------------------------------------------
function message(obj) {
     
	obj.name = 'Tom';
}
var obj = new Object();
message(obj);									// obj.name = 'Tom'
--------------------------------------------------------------------------------------------------------------------------------
function message(obj) {
     
	obj.name = 'Tom';
	var obj = new Object();
	obj.name = 'Jerry';							// 由于重新声明了一个引用类型,地址不同
}
var obj = new Object();
message(obj);									// obj.name = 'Tom'
  • 全局变量:在外环境中,在任何地方都可以读取使用到的变量,所有的全局变量都是在 window 下
  • 局部变量:在内代码块,仅在内部才能访问使用的变量,函数参数也是局部作用
function message() {
     
	return 'this is message';
}
var msg = 'hello world';
console.log(window.message());					// this is message
console.log(window.msg);						// hello world
--------------------------------------------------------------------------------------------------------------------------------
function message() {
     
	var msg = 'hello world';
	return 'this is message';
}
console.log(window.message());					// this is message
console.log(window.msg);						// undefined
--------------------------------------------------------------------------------------------------------------------------------
function message() {
     
	msg = 'hello world';
	return 'this is message';
}
console.log(window.message());					// this is message
console.log(window.msg);						// hello world (不推荐,全局变量最好写最外面)

作用域链

作用域链核心思想:变量的作用域始终是从里往外走,函数定义会预解析,变量不会

var name = 'tom';
function f() {
     
	name = 'jerry';
}
f();											// name = 'jerry';
--------------------------------------------------------------------------------------------------------------------------------
var name = 'tom';
f();											// name = 'jerry';
function f() {
     
	name = 'jerry';
}
--------------------------------------------------------------------------------------------------------------------------------
function f1() {
     
	var name = 'tom';
	function f2() {
     
		var name = 'jerry';
		function f3() {
     
			var name = 'terry';
			console.log(name);					// name = 'terry'
		}
		f3();
	}
	f2();
}	
--------------------------------------------------------------------------------------------------------------------------------
message();										// 预解析:“miao”
function message() {
     
	console.log('miao');
}	
--------------------------------------------------------------------------------------------------------------------------------
console.log(a);									// undefined
var a = 10;
--------------------------------------------------------------------------------------------------------------------------------
var name = 'tom';
function show() {
     
	console.log(name);
	var name = 'jerry';
}
show();											// undefined
--------------------------------------------------------------------------------------------------------------------------------
console.log(show);								// ƒ show() { console.log('function'); }
function show() {
     
	console.log('function');
}
var show = 'var_value';
console.log(show);								// 'var_value'
--------------------------------------------------------------------------------------------------------------------------------
var name = 'tom';
show();
function show() {
     
	console.log(name);							// undefined
	var name = 'jerry';
}
--------------------------------------------------------------------------------------------------------------------------------
var tom = 'tom';
show();
function show() {
     
	var jerry = 'jerry';
	console.log(tom);							// undefined
	console.log(jerry);							// 'jerry'
	var tom = 'cat';
}
--------------------------------------------------------------------------------------------------------------------------------
show();
console.log(cat);								// 会报错
console.log(mouse);								// 'like'
console.log(dog);								// 'like'
function show() {
     
	var cat = mouse = dog = 'like';				// mouse 和 dog 没有使用 var 是全局变量
	console.log(cat);							// 'like'
    console.log(mouse);							// 'like'
    console.log(dog);							// 'like'
}

异常处理

  • try :测试代码块的错误
  • catch:处理错误
  • throw:创建自定义错误
  • finally:测试代码块后执行,不管有无异常
function message() {
     
	try {
     
		adddlert("Welcome guest!");
	} catch(err) {
     
		console.log(err);
	}
}
message();										// ReferenceError: adddlert is not defined
--------------------------------------------------------------------------------------------------------------------------------
function myFunction(val) {
     
	try {
     
		if(val == '') throw 'empty';
		if(isNaN(val)) throw 'not a number';
		if(val > 10) throw 'too high';
		if(val < 5) throw 'too low';
	} catch(err) {
     
		console.log(err);
	}
}
myFunction(NaN);								// not a number
myFunction('');									// empty
--------------------------------------------------------------------------------------------------------------------------------
function myClear() {
     
	try {
     
		throw new Error('出错了...');
	} finally {
     
		console.log('清理完成');
	}
}
myClear();										// 清理完成
错误属性 属性描述
name 设置或返回一个错误名
message 设置或返回一个错误信息(字符串)
function say() {
     
	try {
     
		add(2, 3);
	} catch(err) {
     
		console.log(err.name);						// ReferenceError
		console.log(err.message);					// ReferenceError
	}
}

数组遍历

数组是一种引用数据类型,属于对象,于普通对象类似,也是用来存储一些值的,不同的是普通对象是使用的字符串作为属性名,而数组使用的是数字来作为索引操作元素

  • 使用 Array 构造函数:var arr = new Array(); 创建一个数组对象,括号内写数字表数组长度
    • 如果不设置数组的长度,只要数组通过下标设置元素值,数组长度会自动添加
    • 如果设置了数组的长度,数组会默认填充长度个数的空值,直到数组基于下标设置元素值
  • 使用数组字面量:var arr = []
    • 如果不设置数组的长度,通过设置非 0 下标元素值时,数组长度会等于设置元素值的下标值,且未设值元素为空值
  • length 使用一般用在取最后一个元素赋值,或用于迭代时次数约束
var arr = new Array();								// arr = []
arr[0] = 2;											// arr = [2]
var arr = new Array(5);								// arr = [empty × 5]
arr[0] = 2;											// arr = [2, empty × 4]
var arr = [];										// arr = []
arr[2] = 2;											// arr = [empty × 2, 2]
数组属性 属性描述
constructor 返回对创建此对象的 Array 函数的引用
prototype 允许您可以向对象添加属性和方法
length 返回数组的长度
Array .constructor;									// Function() { [native code] }
Array .prototype;									// 返回 Array 原型属性和方法
var arr = []; arr.length;							// 0
数组方法 方法描述 数组方法 方法描述
push() 在数组末尾添加一个或多个数组元素 shift() 删除并返回数组的开头第一个元素
unshift() 在数组开头添加数组元素 from() 通过给定的对象中创建一个数组
concat() 合并两个数组 isArray() 判断对象是否为数组
pop() 删除并返回数组的最后一个元素
var arr = [2,4,5,7]; arr.push(8,10);								// [2, 4, 5, 7, 8, 10]
var arr = [2,4,5,7]; arr.unshift(8,10);								// [8, 10, 2, 4, 5, 7]
var arr = [2,4,5,7]; arr.concat([8,10]);							// [2, 4, 5, 7, 8, 10]
var arr = [2,4,5,7]; var item = arr.pop();							// item = 7, arr = [2, 4, 5]
var arr = [2,4,5,7]; var item = arr.shift();						// item = 2, arr = [4, 5, 7]
var arr = Array.from([2,4,5,7]);									// [2,4,5,7]
var arr = Array.from([2,4,5,7], function(x) {
      return x + 1; });		// [3, 5, 6, 8]
var arr = [2,4,5,7]; Array.isArray(arr);							// true
数组方法 方法描述
splice() 删除或插入或替换任意数量的项
slice() 从已有数组中选取部分元素构成新数组
sort() 对数组进行排序
reverse() 将数组反向排列
copyWithin() 从数组的指定位置拷贝元素到数组的另一个指定位置中
fill() 使用一个固定值来填充数组
var arr = [2,4,5,7]; var item = arr.splice(1,2);					// item = [4, 5], arr = [2, 7]
var arr = [2,4,5,7]; arr.splice(1,0,10);							// [2, 10, 4, 5, 7]
var arr = [2,4,5,7]; arr.splice(1,1,10);							// [2, 10, 5, 7]
var arr = [2,4,5,7]; arr.splice(1,0,8,10);							// [2, 8, 10, 4, 5, 7]
var arr = [2,4,5,7]; arr.splice(1,1,8,10);							// [2, 8, 10, 5, 7]
var arr = [2,4,5,7]; arr.splice(1,2,8,10);							// [2, 8, 10, 7]
var arr = [2,4,5,7]; var item = arr.slice(1,2);						// item = [4], arr = [2, 4, 5, 7]
var arr = [2,4,5,7]; arr.sort();									// [2, 4, 5, 7]
var arr = [2,4,5,7]; arr.sort(function(a, b) {
      return a > b; });	// [2, 4, 5, 7]
var arr = [2,4,5,7]; arr.sort(function(a, b) {
      return a < b; });	// [7, 5, 4, 2]
var arr = [2,4,5,7]; arr.reverse();									// [7, 5, 4, 2]
var arr = [2,4,5,7]; arr.copyWithin(2,0);							// [2, 4, 2, 4]
var arr = [2,4,5,7]; arr.fill(8);									// [8, 8, 8, 8]
数组方法 方法描述
valueOf() 返回数组对象的原始值
toString() 将数组转换为字符串并返回
toLocaleString() 将数组转换为本地格式字符串并返回
join() 用指定分隔符分割数组并转换为字符串返回
indexOf() 从数组的起始位置开始查找匹配字符位置
lastIndexOf() 从数组的结束位置开始查找匹配字符位置
find() 返回符合传入测试(函数)条件的数组元素
findIndex() 返回符合传入测试(函数)条件的数组元素索引
includes() 判断一个数组是否包含一个指定的值
var arr = [2,4,5,7]; arr.valueOf();										// [2, 4, 5, 7]
var arr = [2,4,5,7]; arr.toString();									// "2,4,5,7"
var arr = [2,4,5,7]; arr.toLocaleString();								// "2,4,5,7"
var arr = [2,4,5,7]; arr.join('-');										// "2-4-5-7"
var arr = [2,4,5,7]; arr.indexOf(4);									// 1
var arr = [2,4,5,7]; arr.indexOf(4,2);									// -1 (第二个参数表示从那个索引开始)
var arr = [2,4,5,7]; arr.indexOf(4,-3);									// 1
var arr = [2,4,5,7]; arr.lastIndexOf(5);								// 2
var arr = [2,4,5,7]; arr.lastIndexOf(5,2);								// 2
var arr = [2,4,5,7]; arr.lastIndexOf(5,-1);								// 2
var arr = [2,4,5,7]; arr.find(function(val){
      return val > 4; });		// 5 找到第一个满足条件的元素
var arr = [2,4,5,7]; arr.findIndex(function(val){
      return val > 4; });	// 2 找到第一个满足条件的元素索引
var arr = [2,4,5,7]; arr.includes(2);									// true
var arr = [2,4,5,7]; arr.includes(2,1);									// false
数组方法 方法描述 数组方法 方法描述
entries() 返回数组的可迭代对象 map() 通过指定函数处理数组的每个元素,并返回处理后的数组
keys() 返回数组的可迭代对象,包含原始数组的键(key) some() 检测数组元素中是否有元素符合指定条件
every() 检测数组元素的每个元素是否都符合条件 reduce() 将数组元素计算为一个值(从左到右)
filter() 检测数组元素,并返回符合条件所有元素的数组 reduceRight() 将数组元素计算为一个值(从右到左)
forEach() 数组每个元素都执行一次回调函数
var arr = [2,4,5,7]; var item = arr.entries();							// item.next().value in [0, 2], [1, 4], [2, 5], [3, 7]
var arr = [2,4,5,7]; var item = arr.keys();								// item.next().value in 0,1,2,3
var arr = [2,4,5,7]; arr.every(function(val) {
      return val > 4; });		// false (判断所有元素匹配)
var arr = [2,4,5,7]; arr.filter(function(val) {
      return val > 4; });		// [5, 7]
var arr = [2,4,5,7]; arr.forEach(function(item, index) {
      return {
     index: index, item: item} });
var arr = [4,9,16,25]; arr.map(Math.sqrt);								// [2, 3, 4, 5]
var arr = [2,4,5,7]; arr.some(function(val) {
      return val > 4; })						// true (存在就返回 true)
var arr = [2,4,5,7]; arr.reduce(function(total, num) {
      return total + num; })			// 18
var arr = [2,4,5,7]; arr.reduceRight(function(total, num) {
      return total + num; })		// 18

数组排序

包括:原生排序、冒泡排序、快速排序、插入排序、选择排序,其中性能最好的是快速排序

原生排序: 
var arr = [1, 4, -8, -3, 6, 12, 9, 8];
arr.sort(function(bef, aft) {
      return bef - aft; });					// [-8, -3, 1, 4, 6, 8, 9, 12]
arr.sort(function(bef, aft) {
      return aft - bef; });					// [12, 9, 8, 6, 4, 1, -3, -8]
--------------------------------------------------------------------------------------------------------------------------------
冒泡排序:
var arr = [1, 4, -8, -3, 6, 12, 9, 8];
for(var j = 0; j < arr.length - 1; j++) {
     
	// 两两比较,如果前者比后者大,则交换位置
	for(var i = 0; i < arr.length - 1 - j; i++) {
     
		if(arr[i] > arr[i + 1]) {
     
			var temp = arr[i];
			arr[i] = arr[i + 1];
			arr[i + 1] = temp;
		}
	}
}																	// [-8, -3, 1, 4, 6, 8, 9, 12]
for(var j = 0; j < arr.length - 1; j++) {
     
	// 两两比较,如果前者比后者大,则交换位置
	for(var i = 0; i < arr.length - 1 - j; i++) {
     
		if(arr[i] < arr[i + 1]) {
     
			var temp = arr[i];
			arr[i] = arr[i + 1];
			arr[i + 1] = temp;
		}
	}
}																	// [12, 9, 8, 6, 4, 1, -3, -8]
--------------------------------------------------------------------------------------------------------------------------------
快速排序:
var arr = [1, 4, -8, -3, 6, 12, 9, 8];
function quickSort(arr) {
     
	if(arr.length === 0) return arr;
	var index = Math.floor(arr.length / 2),							// 定义中间值的索引
		temp = arr.splice(index, 1),								// 获取中间值
		left = [], right = [];										// 定义左右两部分数组
	for(var i = 0; i < arr.length; i++) {
     
		// 如果元素比中间值小,那么放在左边数组,否则放在右边数组中
		if(arr[i] < temp) {
     
			left.push(arr[i]);
		} else {
     
			right.push(arr[i]);
		}
	}
	return quickSort(left).concat(temp, quickSort(right));
}
quickSort(arr);														// [-8, -3, 1, 4, 6, 8, 9, 12]
--------------------------------------------------------------------------------------------------------------------------------
插入排序:
var arr = [1, 4, -8, -3, 6, 12, 9, 8];
function insertSort(arr) {
     
	// 假设第 0 元素是有序序列,第 1 元素之后是无序的序列,从第 1 元素开始依次将无序序列的元素插入到有序序列中
	for(var i = 1; i < arr.length; i++) {
     
		if(arr[i] < arr[i - 1]) {
     
			// 取出无序序列中需要插入的第 i 个元素
			var temp = arr[i];
			// 定义有序中的最后一个位置
			var j = i - 1;
			arr[i] = arr[j];
			// 比较大小,找到插入的位置
			while(j >= 0 && temp < arr[j]) {
     
				arr[j + 1] = arr[j];
				j--;
			};
			// 插入数据
			arr[j + 1] = temp;
		}
	}
}
insertSort(arr);													// [-8, -3, 1, 4, 6, 8, 9, 12]
--------------------------------------------------------------------------------------------------------------------------------
选择排序:
var arr = [1, 4, -8, -3, 6, 12, 9, 8];
function selectSort(arr) {
     
	for(var i = 0; i < arr.length; i++) {
     
		// 设置当前范围最小值和索引
		var min = arr[i];
		var minIndex = i;
		// 在该范围选出最小值
		for(var j = i + 1; j < arr.length; j++) {
     
			if(min > arr[j]) {
     
				min = arr[j];
				minIndex = j;
			}
		}
		// 将最小值插入,并将原来位置的最小值删除
		arr.splice(i, 0, min);
		arr.splice(minIndex + 1, 1);
	}
}
selectSort(arr);													// [-8, -3, 1, 4, 6, 8, 9, 12]

日期时间

Date 对象用于处理日期与时间,采用 UTC(Coordinated Universal Time,国际协调时间)1970 年 1 月 1 日午夜(零时)开始经过的毫秒来保存的日期。

  • 使用 Date 构造函数:var now= new Date(); 创建一个日期对象,不传参数(数值为:毫秒数)默认返回当前系统时间
var now= new Date();							// Wed Jul 22 2020 17:44:53 GMT+0800 (中国标准时间)
-- Wed 当前星期
-- Jul 当前月份
-- 22  当前日期
-- 2020 当前年份
-- 17:44:53 时分秒
-- GMT+0800 表示东八区(中国北京时区)
var now = new Date(-1);							// Thu Jan 01 1970 07:59:59 GMT+0800 (中国标准时间)
var now = new Date(6000);						// Thu Jan 01 1970 08:00:06 GMT+0800 (中国标准时间)
var now = new Date(-6000);						// Thu Jan 01 1970 07:59:54 GMT+0800 (中国标准时间)
var now = new Date('2020-01-03 12:02:33');		// Fri Jan 03 2020 12:02:33 GMT+0800 (中国标准时间)
var now = new Date('2020-01-33 12:02:33');		// Invalid Date 有些浏览器会把对出的日期进位到下个月
日期属性 属性描述
constructor 返回对创建此对象的 Date 函数的引用
prototype 允许您可以向对象添加属性和方法
Date.constructor;								// Function() { [native code] }
Date.prototype;									// 返回 Date 原型属性和方法
日期常用方法 方法描述 日期常用方法 方法描述
getFullYear() 从 Date 对象以四位数字返回年份 getMinutes() 返回 Date 对象的分钟 (0 ~ 59)
getMonth() 从 Date 对象返回月份 (0 ~ 11),结果加 1 getSeconds() 返回 Date 对象的秒数 (0 ~ 59)
getDate() 从 Date 对象返回一个月中的某一天 (1 ~ 31) getMilliseconds() 返回 Date 对象的毫秒(0 ~ 999)
getDay() 从 Date 对象返回一周中的某一天 (0 ~ 6),0 表示周日 getTime() 返回 1970 年 1 月 1 日至今的毫秒数
getHours() 返回 Date 对象的小时 (0 ~ 23)
var now = new Date();
var yyyy = now.getFullYear();
var mm = now.getMonth() + 1;
var dd = now.getDate();
var d  = now.getDay();
var h  = now.getHours();
var m  = now.getMinutes();
var s  = now.getSeconds();
var ms = now.getMilliseconds();
var t  = now.getTime();
日期常用方法 方法描述 日期常用方法 方法描述
setFullYear() 设置 Date 对象中的年份(四位数字) setMinutes() 设置 Date 对象中的分钟 (0 ~ 59)
setMonth() 设置 Date 对象中月份 (0 ~ 11) setSeconds() 设置 Date 对象中的秒钟 (0 ~ 59)
setDate() 设置 Date 对象中月的某一天 (1 ~ 31) setMilliseconds() 设置 Date 对象中的毫秒 (0 ~ 999)
setHours() 设置 Date 对象中的小时 (0 ~ 23) setTime() setTime() 方法以毫秒设置 Date 对象
var now = new Date();								// Wed Jul 22 2020 18:14:46 GMT+0800 (中国标准时间)
now.setFullYear(2021);								// Thu Jul 22 2021 18:15:21 GMT+0800 (中国标准时间)
now.setMonth(1);									// Sat Feb 22 2020 18:31:06 GMT+0800 (中国标准时间) ———— 下个月的今天
now.setMonth(-1);									// Sun Dec 22 2019 18:30:26 GMT+0800 (中国标准时间) ———— 上个月的今天
now.setDate(2);										// Thu Jul 02 2020 18:32:06 GMT+0800 (中国标准时间) ———— 02 号日期的当前时间
now.setDate(-2);									// Sun Jun 28 2020 18:33:26 GMT+0800 (中国标准时间) ———— 上个月的倒数第二天
now.setHours(10);									// Wed Jul 22 2020 10:34:15 GMT+0800 (中国标准时间) ———— 10 点的当前分钟时间
now.setMinutes(-2);									// Wed Jul 22 2020 17:58:26 GMT+0800 (中国标准时间) ———— 上个小时的倒数第二分钟
now.setDate(now.getDate() - 2);						// Mon Jul 20 2020 18:38:19 GMT+0800 (中国标准时间) ———— 前两天的当前时间
now.setDate(now.getDate() + 2);						// Mon Jul 24 2020 18:38:19 GMT+0800 (中国标准时间) ———— 后两天的当前时间
PS:单纯的使用 SET 仅仅是修改当前时间,而通过当前时间进行计算设置才等到往后的设置时间
日期常用方法 方法描述 日期常用方法 方法描述
valueOf() 返回 Date 对象的原始值 toJSON() 以 JSON 数据格式返回日期字符串
toString() 把 Date 对象转换为字符串 toLocaleDateString() 根据本地时间格式,把 Date 对象的日期部分转换为字符串
toTimeString() 把 Date 对象的时间部分转换为字符串 toLocaleTimeString() 根据本地时间格式,把 Date 对象的时间部分转换为字符串
toDateString() 把 Date 对象的日期部分转换为字符串 toLocaleString() 根据本地时间格式,把 Date 对象转换为字符串
toISOString() 使用 ISO 标准返回字符串的日期格式
var now = new Date();								// Wed Jul 22 2020 18:48:57 GMT+0800 (中国标准时间)
now.valueOf();										// 1595414937833
now.toString();										// Wed Jul 22 2020 18:48:57 GMT+0800 (中国标准时间)
now.toTimeString();									// 18:48:57 GMT+0800 (中国标准时间)
now.toDateString();									// Wed Jul 22 2020
now.toISOString();									// 2020-07-22T10:48:57.833Z
now.toJSON();										// 2020-07-22T10:48:57.833Z
now.toLocaleDateString();							// 2020/7/22
now.toLocaleTimeString();							// 下午6:48:57
now.toLocaleString();								// 2020/7/22 下午6:48:57
日期方法 方法描述 日期方法 方法描述
UTC() 根据世界时返回 1970 年 1 月 1 日 到指定日期的毫秒数 getTimezoneOffset() 返回本地时间与格林威治标准时间 (GMT) 的分钟差
toUTCString() 根据世界时,把 Date 对象转换为字符串 setUTCFullYear() 根据世界时设置 Date 对象中的年份(四位数字)
getUTCFullYear() 根据世界时从 Date 对象返回四位数的年份 setUTCMonth() 根据世界时设置 Date 对象中的月份 (0 ~ 11)
getUTCMonth() 根据世界时从 Date 对象返回月份 (0 ~ 11) setUTCDate() 根据世界时设置 Date 对象中月份的一天 (1 ~ 31)
getUTCDate() 根据世界时从 Date 对象返回月中的一天 (1 ~ 31) setUTCHours() 根据世界时设置 Date 对象中的小时 (0 ~ 23)
getUTCDay() 根据世界时从 Date 对象返回周中的一天 (0 ~ 6) setUTCMinutes() 根据世界时设置 Date 对象中的分钟 (0 ~ 59)
getUTCHours() 根据世界时返回 Date 对象的小时 (0 ~ 23) setUTCSeconds() setUTCSeconds() 方法用于根据世界时 (UTC) 设置指定时间的秒字段
getUTCMinutes() 根据世界时返回 Date 对象的分钟 (0 ~ 59) setUTCMilliseconds() 根据世界时设置 Date 对象中的毫秒 (0 ~ 999)
getUTCSeconds() 根据世界时返回 Date 对象的秒钟 (0 ~ 59) parse() 返回1970年1月1日午夜到指定日期(字符串)的毫秒数
getUTCMilliseconds() 根据世界时返回 Date 对象的毫秒(0 ~ 999)

日期处理

/**
 * 对 Date 的扩展,将 Date 转化为指定格式的 String 日期格式
 * 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
 * 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符
 * @param  {[Date]} date [需要转化格式的日期时间]
 * @param  {[String]} fmt  [转化格式]
 * @return {[String]}      [返回转化后的格式化日期字符]
 * dateFormat(new Date(), 'yyyy-MM-dd hh:mm:ss.S') ==> 2020-07-22 21:54:08.58
 * dateFormat(new Date(), 'yyyy-M-d h:m:s.S') ==> 2020-7-22 21:54:8.58
 */
function dateFormat(date, fmt) {
     
	var o = {
     
        "M+": date.getMonth() + 1, //月份
        "d+": date.getDate(), //日
        "h+": date.getHours(), //小时
        "m+": date.getMinutes(), //分
        "s+": date.getSeconds(), //秒
        "q+": Math.floor((date.getMonth() + 3) / 3), //季度
        "S": date.getMilliseconds() //毫秒
    };
    if (/(y+)/.test(fmt)) {
     
    	fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
    }
    for (var k in o) {
     
    	if (new RegExp("(" + k + ")").test(fmt)) {
     
    		fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    	}
    }
    return fmt;
}
var date = dateFormat(new Date(), 'yyyy-MM-dd hh:mm:ss.S');
--------------------------------------------------------------------------------------------------------------------------------
/**
 * 对 Date 的扩展,通过传递一个日期时间,根据调整模式判断调整对应模式的日期时间
 * @param  {[Date]} date  [传递过来的参考日期时间]
 * @param  {[String]} mode  [传过来的调整模式:M 月、d 天、h 时、m 分、s 秒]
 * @param  {[Number]} value [正数: 当前时间后时间,负数: 当前时间前时间]
 * @return {[Date]}       [返回处理后的日期时间]
 * 得到当前系统时间 var now = new Date(); ==> Wed Jul 22 2020 22:10:30 GMT+0800 (中国标准时间)
 * dateInterval(new Date(), 'd', -1); ==> Tue Jul 21 2020 22:10:25 GMT+0800 (中国标准时间)
 */
function dateInterval(date, mode, value) {
     
	switch(mode) {
     
		case 'M': date.setMonth(date.getMonth() + value); break;
		case 'd': date.setDate(date.getDate() + value); break;
		case 'h': date.setHours(date.getHours() + value); break;
		case 'm': date.setMinutes(date.getMinutes() + value); break;
		case 's': date.setSeconds(date.getSeconds() + value); break;
	}
	return date;
}
var date = dateInterval(new Date(), 'd', -1);

全局对象

全局属性 属性描述
Infinity 代表正的无穷大的数值。
NaN 指示某个值是不是数字值。
undefined 指示未定义的值
函数 描述 函数 描述
decodeURI() 解码某个编码的 URI isNaN() 检查某个值是否是数字
decodeURIComponent() 解码一个编码的 URI 组件 Number() 把对象的值转换为数字
encodeURI() 把字符串编码为 URI parseFloat() 解析一个字符串并返回一个浮点数
encodeURIComponent() 把字符串编码为 URI 组件 parseInt() 解析一个字符串并返回一个整数
escape() 对字符串进行编码 String() 把对象的值转换为字符串
eval() 计算 JavaScript 字符串,并把它作为脚本代码来执行 unescape() 对由 escape() 编码的字符串进行解码
isFinite() 检查某个值是否为有穷大的数
拷贝右侧地址:https://www.baidu.com/s?wd=码云,放入浏览器地址栏输入框中,变成:
https://www.baidu.com/s?wd=%E7%A0%81%E4%BA%91
这个就是浏览器自动将中文转码了
encodeURIComponent('码云') === "%E7%A0%81%E4%BA%91" 由于浏览器地址栏不能识别中文,需要将中文转换为 unicode 码
------------------------------------------------------------------------------------------------------------
eval("var a = 1"); console.log(a);							// 1 用于声明 a 变量并赋值
var item = eval("({b:2})");									// item = {b:2}
var num = NaN; isNaN(num);									// true
var num = 100; isNaN(num);									// false
var str = 'hello world'; escape(str);						// hello%20world
var str = 'hello%20world'; unescape(str);					// "hello world"
var str = '0.26ab'; parseFloat(str);						// 0.26
var str = 'cd0.26ab'; parseFloat(str);						// NaN
var str = '0.26a34'; parseFloat(str);						// 0.26
var str = '1.56ab'; parseInt(str);							// 1 不会四舍五入,只截取整数位

数学函数

数学属性 属性描述 数学属性 属性描述
E 返回算术常量 e,即自然对数的底数(约等于2.718) LOG10E 返回以 10 为底的 e 的对数(约等于0.434)
LN2 返回 2 的自然对数(约等于0.693) PI 返回圆周率(约等于3.14159)
LN10 返回 10 的自然对数(约等于2.302) SQRT1_2 返回 2 的平方根的倒数(约等于 0.707)
LOG2E 返回以 2 为底的 e 的对数(约等于 1.4426950408889634) SQRT2 返回 2 的平方根(约等于 1.414)
Math.E;								// 2.718281828459045
Math.LN2;							// 0.6931471805599453
Math.LN10;							// 2.302585092994046
Math.LOG2E;							// 1.4426950408889634
Math.LOG10E;						// 0.4342944819032518
Math.PI;							// 3.141592653589793
Math.SQRT1_2;						// 0.7071067811865476
Math.SQRT2;							// 1.4142135623730951
方法 描述 方法 描述
abs(x) 返回 x 的绝对值 log(x) 返回数的自然对数(底为e)
acos(x) 返回 x 的反余弦值 max(x,y,z,…,n) 返回 x,y,z,…,n 中的最高值
asin(x) 返回 x 的反正弦值 min(x,y,z,…,n) 返回 x,y,z,…,n中的最低值
atan(x) 以介于 -PI/2 与 PI/2 弧度之间的数值来返回 x 的反正切值 pow(x,y) 返回 x 的 y 次幂
atan2(y,x) 返回从 x 轴到点 (x,y) 的角度(介于 -PI/2 与 PI/2 弧度之间) random() 返回 0 ~ 1 之间的随机数
ceil(x) 对数进行上舍入 round(x) 四舍五入
cos(x) 返回数的余弦 sin(x) 返回数的正弦
exp(x) 返回 Ex 的指数 sqrt(x) 返回数的平方根
floor(x) 对 x 进行下舍入 tan(x) 返回角的正切
Math.abs(-7.25);					// 7.25
Math.ceil(1.4)						// 2 向上取整
Math.floor(1.6);					// 1 向下取整
Math.round(2.5);					// 3 四舍五入
Math.max(5,10);						// 10 最大值
Math.min(5,10);						// 5 最小值
Math.random();						// 0.1741323729201285 随机数
Math.atan2(8,4);					// 1.1071487177940904 求弧度
Math.sin(3);						// 0.1411200080598672 正弦值
Math.cos(3);						// -0.9899924966004454 余弦值
Math.tan(90);						// -1.995200412208242 正切值
Math.asin(0.5);						// 0.5235987755982989 反正弦值
Math.acos(0.5);						// 1.0471975511965979 反余弦值
Math.atan(2);						// 1.1071487177940904 反正切值
Math.pow(4,3);						// 64 次方数
Math.sqrt(9);						// 3 开方数
Math.exp(1);						// 2.718281828459045 求指数
Math.log(2);						// 0.6931471805599453 求对数

正则匹配

是一个描述字符模式的对象,主要用来验证客户端的输入数据

  • 使用 RegExp 构造函数:var reg= new RegExp(); 创建一个正则对象,括号内第一个字符参数,表示匹配字符,第二个参数匹配模型
  • 使用字面量格式创建:var reg = //; 直接使用两个反斜杠,中间位匹配参数,后面为匹配模式设置
修饰符 描述
i 执行对大小写不敏感的匹配
g 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)
m 执行多行匹配
var reg = /hi/i, str = 'hi world'; reg.test(str);					// true
var reg = /hi/g, str = 'Hi world'; reg.test(str);					// false
var reg = /hi/m, str = 'Hi world, hi world'; reg.test(str);			// true
var reg = /hi/ig, str = 'Hi world'; reg.test(str);					// true
var reg = /hi/igm, str = 'Hi world, Hi world'; reg.test(str);		// true
表达式 表达式 描述
[abc] 查找方括号之间的任何字符 [A-z] 查找任何从大写 A 到小写 z 的字符
[^abc] 查找任何不在方括号之间的字符 [adgk] 查找给定集合内的任何字符
[0-9] 查找任何从 0 至 9 的数字 [^adgk] 查找给定集合外的任何字符
[a-z] 查找任何从小写 a 到小写 z 的字符 (red\ blue\
[A-Z] 查找任何从大写 A 到大写 Z 的字符
var reg = /[abc]/; str = 'd'; reg.test(str);						// false
var reg = /[^abc]/; str = 'd'; reg.test(str);						// true
var reg = /[a-z]/; str = 'd'; reg.test(str);						// true
var reg = /[A-Z]/; str = 'd'; reg.test(str);						// false
var reg = /[0-9]/; str = '3'; reg.test(str);						// true
var reg = /[a-z0-9]/; str = 'd'; reg.test(str);						// true
var reg = /[A-Z0-9]/i; str = 'd'; reg.test(str);					// true
var reg = /[a-zA-Z0-9]/; str = 'd'; reg.test(str);					// true
元字符 描述 元字符 描述
. 查找单个字符,除了换行和行结束符 \0 查找 NULL 字符
\w 查找单词字符 \n 查找换行符
\W 查找非单词字符 \f 查找换页符
\d 查找数字 \r 查找回车符
\D 查找非数字字符 \t 查找制表符
\s 查找空白字符 \v 查找垂直制表符
\S 查找非空白字符 \xxx 查找以八进制数 xxx 规定的字符
\b 匹配单词边界 \xdd 查找以十六进制数 dd 规定的字符
\B 匹配非单词边界 \uxxxx 查找以十六进制数 xxxx 规定的 Unicode 字符
量词 描述
n+ 匹配任何包含至少一个 n 的字符串。例如,/a+/ 匹配 “candy” 中的 “a”,“caaaaaaandy” 中所有的 “a”
n* 匹配任何包含零个或多个 n 的字符串。例如,/bo*/ 匹配 “A ghost booooed” 中的 “boooo”,“A bird warbled” 中的 “b”,但是不匹配 “A goat grunted”
n? 匹配任何包含零个或一个 n 的字符串。例如,/e?le?/ 匹配 “angel” 中的 “el”,“angle” 中的 “le”
n{X} 匹配包含 X 个 n 的序列的字符串。例如,/a{2}/ 不匹配 “candy,” 中的 “a”,但是匹配 “caandy,” 中的两个 “a”,且匹配 “caaandy.” 中的前两个 “a”
n{X,} X 是一个正整数。前面的模式 n 连续出现至少 X 次时匹配。例如,/a{2,}/ 不匹配 “candy” 中的 “a”,但是匹配 “caandy” 和 “caaaaaaandy.” 中所有的 “a”
n{X,Y} X 和 Y 为正整数。前面的模式 n 连续出现至少 X 次,至多 Y 次时匹配。例如,/a{1,3}/ 不匹配 “cndy”,匹配 “candy,” 中的 “a”,“caandy,” 中的两个 “a”,匹配 “caaaaaaandy” 中的前面三个 “a”。注意,当匹配 “caaaaaaandy” 时,即使原始字符串拥有更多的 “a”,匹配项也是 “aaa”
n$ 匹配任何结尾为 n 的字符串
^n 匹配任何开头为 n 的字符串
?=n 匹配任何其后紧接指定字符串 n 的字符串
?!n 匹配任何其后没有紧接指定字符串 n 的字符串
属性 描述 属性 描述
constructor 返回一个函数,该函数是一个创建 RegExp 对象的原型 lastIndex 用于规定下次匹配的起始位置
global 判断是否设置了 “g” 修饰符 multiline 判断是否设置了 “m” 修饰符
ignoreCase 判断是否设置了 “i” 修饰符 source 返回正则表达式的匹配模式
var reg = new RegExp('baidu', 'g'); reg.constructor;							// ƒ RegExp() { [native code] }
var reg = new RegExp('baidu', 'g'); reg.global;									// true
var reg = new RegExp('baidu', 'i'); reg.ignoreCase;								// false
var reg = /hi/m, str = 'Hi world, hi world'; reg.test(str); reg.lastIndex;		// 0
var reg = new RegExp('baidu', 'i'); reg.multiline;								// false
var reg = /hi/m, str = 'Hi world, hi world'; reg.test(str); reg.source;			// "hi"
方法 描述
exec() 检索字符串中指定的值。返回找到的值,并确定其位置
test() 检索字符串中指定的值。返回 true 或 false
toString() 返回正则表达式的字符串
var reg = /hi/m, str = 'Hi world, hi world'; reg.exec(str);	// ["hi", index: 10, input: "Hi world, hi world", groups: undefined]
var reg = /hi/m, str = 'Hi world, hi world'; reg.test(str);	// true
var reg = new RegExp('baidu', 'g'); reg.toString();			// "/baidu/g"
方法 描述 方法 描述 FF IE
search() 检索与正则表达式相匹配的值 replace() 替换与正则表达式匹配的子串 1 4
match() 找到一个或多个正则表达式的匹配 split() 把字符串分割为字符串数组 1 4
var str = 'Hi world, hi world'; str.search('hi');			// 10
var str = 'Hi world, hi world'; str.search(/hi/);			// 10
var str = 'Hi world, hi world'; str.match(/hi/i);			// ["Hi", index: 0, input: "Hi world, hi world", groups: undefined]
var str = 'Hi world, hi world'; str.replace('hi', 'hello');	// "Hi world, hello world"
var str = 'Hi world, hi world'; str.replace(/hi/, 'hello');	// "Hi world, hello world"
var str = 'Hi world, hi world'; str.replace(/hi/i, 'hello');// "hello world, hi world"
var str = 'Hi world, hi world'; str.replace(/hi/ig, 'hello');// "hello world, hello world"
var str = '2020/02/20'; str.replace(/([0-9]{4})\/([0-9]{2})\/([0-9]{2})/, '$1-$2-$3');	// "2020-02-20" 每个括号匹配为一个 $ 元素
var tel = '13870243598'; tel.replace(/([0-9]{3})([0-9]{4})([0-9]{4})/, '$1****$3');		// "138****3598"
var str = '2020-02-20'; str.split(/-/);						// ["2020", "02", "20"]

常用正则表达式

验证信息 正则表达式
验证账号:只能使用字母开头,数字混合组成不能低以 6 位高于 20 位 /^[a-zA-Z][0-9a-zA-Z]{5,19}$/
验证密码:只能使用字母数字混合组成,不能低于 8 位高于 30 位 /^[0-9a-zA-Z]{8,30}$/
验证码:4 - 6 位数字型、6 - 8 位数字字母混合型 /^[0-9]{4}$/、/^[0-9]{6}$/、/^[0-9a-zA-Z]{6}$/、/^[0-9a-zA-Z]{8}$/
验证手机号:手机号码总共 11 位,第一位 1 开头 /^1[3456789]\d{9}$/
验证身份证:15 位 或 18 位,且有带 X 字符的 /^\d{6}(18|19|20)?\d{2})?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])\d{3}\(\d|X)$/
验证邮箱:必须存在 @ 和 . 且两者之间有其他字符 /^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$/
验证中文名字:两位到四位中文 /^\[\u0391-\uFFE5]{2,4}$/
验证域名:服务器 IP 地址 /^[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?$/
验证地址:网站地址,固定 http:// 或 https:// /^([a-zA-z]+://[^\s]*)|(^http://([\w-]+\.)+[\w-]+([\w-./?%&=]*)?$$/

你可能感兴趣的:(学习笔记,javascript,前端)