共计 12266 个字符,预计需要花费 31 分钟才能阅读完成。
JS 代码原则:高内聚,弱耦合
- ecmascript 是一种语言标准,第一版标准发布于 1997 年,javascript 是网景公司对 ecmascript 标准的一种实现。
- js 不区分整数和浮点数,统一用 number 表示,nan 表示 not a number, 无法计算结果的时候用 nan 表示。
- 字符串 string, 是以单引号或者双引号括起来的任意文本,比如 ’abc’,”abc”.
- 布尔值 boolean, 布尔值只有两种值,true 或者 false。
- && 与,|| 或,!非。
- 编程形式的区别:面向对象、面向过程
- typeof: 六种数据类型:number string boolean undefined object function
typeof 返回的是对象的两个 object:null 和{}
- 浏览器组成
shell 部分
内核部分
渲染引擎(html 和 css 基础语法识别、语法规则和渲染)
js 引擎
其他模块
2008 年谷歌发布最新浏览器 chrome,能把 js 代码直接转化成机械码来执行。
- js 特点
js 是解释性语言(浏览器读一行翻译一行,php/python 也是解释性语言)
优点:跨平台、单线程(异步传输数据:)
不足:速度较慢
- js 标准
标准是由 ecma 制定的 所以有时候也叫 ecmascript
延申两个部分 dom bom
js 三大部分:ecmascript、dom、bom
js 执行队列:单线程,解释性语言,异步传输
- 主流浏览器的内核及私有前缀
ie 内核:trident 私有前缀:-ms-
chrome webkit/blink -webkit-
firefox gecko -moz-
opera presto -o-
safari webkit -webkit-
- 前端开发要求:结构(html)、行为 (js)、样式(css) 相分离
- js 变量(声明变量的只有 var,浮点型)
变量命名规则:必须以英文字母、下划线和 $ 开头;变量名可以包含英文字母、下划线、$ 和数字;不可以用特殊语法(关键字)和保留字作为变量名;
- js 基本语法
数据类型:
常见的数据类型:number string Boolean undefined object function
引用值和原始值唯一的不同是赋值形式不同
原始值:number boolean(true 是 1,false 是 0)string(字符串) undefined(变量没有赋值)null(表示占位,值为空)属于 object 类型
存放地方不一样
原始值是存放在栈(stack)里面的“先进后出”引用值和原始值唯一的根本区别是赋值形式不同。原始值是不可改变的,一个房间已经写了一个值,不可以改变。
删除数据的时候并不会删除数据在内存中的位置,只是让数据包的编号名字与该数据不对应,无从查找,但是依旧存在在内存中。只能二次覆盖。
栈内存之间的赋值是拷贝,互相不影响,定义的进去的值不可改变
var z = 10;
var x = z;
z = 20;
document.write(x);
// 输出的 x 值是 10; 引用值:array object function data regexp
引用值是存放在堆(heap)里面的
引用值拷贝引用值拷贝过去的是地址
var arr = [1,2];
var arr1 = arr;
arr.push(5);
document.write(arr1);
// 输出值为 1 2 5
基本语法
一行结束必须添加分号;程序读取代码一行是识别分号,(函数 function for 循环 if 之后不需要加;(分号)function for 循环 if 判断语句)
任何符号的两侧必须要有一个空格
错误分为两种
低级错误:
不可以写中文字符,语法解析错误
控制台会显示如下:
uncaught syntaxerror:
invalid or unexpected token:
js 运算符
0/0 = NaN,0%0 = NaN
1%0 = NaN,-1%0 = NaN
1/0 = infinity infinity 是数字类型的 number
-1/0 = -infinity
+:数字运算、字符串连接(隐式转换两边都是字符串);
任何数据类型加字符串都等于字符串(隐式转换 +)
%:取余
var rr = 3;
rr %= 4;
document.write(rr);
// 输出的值是 3
// 调换 aa bb 的值
var aa = 123;
var bb = 234;
var temp = aa;
aa = bb;
bb = temp;
document.write(aa);
document.write("<br>");
document.write(bb);
Boolean:false 和 true
字符串比较的是 asc 码的顺序
逻辑运算符
&&(与):(与 是碰到假就返回当前的值)
先看第一个表达式转换成布尔值结果,如果结果为真,那么它会看第二个表达式转换为布尔值的结果,然后如果只有两个表达式的话,那么看到第二个表达式,就可以返回该(第二个)表达式的值了。
var a = 1 && 2 + 2; 返回的值为 4,因为第一个先看 var a = 1 的值是否为真,在该例子中为真,则返回 && 后面的(最后一个值)计算结果 4;
返回结果为 false 的:undfined,null,NaN,“”,0,false。
var a = 0 && 2 + 2; 返回的值为 0,因为第一个是假,直接返回第一个值。
var a = undefined && 2 + 2;返回值为 undefined。
&& 升级:中断作用,短路语句:检查该语句是否存在错误或者能否执行。
data && function(data);如果 data 返回 false 则表示 data 数据不存在或者错误。
||(或):(碰到真就返回当前的值)
|| 或运算符经常用于实现解决浏览器的兼容问题
!(非):
for 循环的执行顺序:
for (var i = 0; i < 10; i ++)
- var i = 0;
- if(i < 10){} 条件判断
- i ++
- if (i < 10){}
- i ++
- if(i < 10){}
条件语句
if 和 else 直接的语句必须是互斥的,满足条件 1 一定不满足其余条件。
i++ 先使用 i,再进行计算 i = i + 1;
小练习:
计算 2 的 n 次幂,n 可输入,n 为自然数:
var n = parseint(window.prompt(“input number”));
// 先定义一个 mul 的初始值
var mul = 1;
for(i = 1;i <= n; i++);{
// 2 的 n 次幂
// 2 的一次幂代表 1 乘以一个 2
// 2 的二次幂代表 1 乘以 2 的值再乘以一个 2
mul *= 2;
}
document.write(mul);
计算 n 的阶乘,n 可输入
var n = parseint(window.prompt(“input a number”));
var jiemul = 1;
for(var i = 1;i <= n; i ++)
{jiemul *= i;}
document.write(jiemul);
输入 a,b,c, 三个数字,打印出最大的
// 因为要输入三个数,所以要写三个 parseint
var a = parseint(window.prompt(“input a”);
var b = parseint(window.prompt(“input b”);
var c = parseint(window.prompt(“input c”);
if(a > b){if(a > c){document.write(a);
}
else{document.write(c);
}
}
else{if(b > c){document.write(b);
}
else{document.write(c);
}}
条件语句
输入星期时,显示工作或者休息
var date = window.prompt('input');
switch (date) {
case "monday":
case "tuesday":
case "wednesday":
case "thursday":
case "friday":
console.log('working');
break;
case "saturday":
case "sunday":
console.log('relaxing');
break;
}
typeof 操作符:
可以返回 6 个值:number string Boolean object undefined function
显示类型转换:
Number:将输入的内容转化成数字
String:将输入的内容转化成字符串:
var demo ="123.3";
var num = String(demo);
console.log(typeof(num) + ":" + num);
隐式类型转换:
逗号操作符:英文的,
例如:1,2 的返回结果就是逗号后面的值为 2,始终返回最后一个逗号后面的值
console.log(isNaN("abc"));
// 输出 true:隐式转化
console.log(isNaN(null));
// 输出 false
//false 是 0,true 是 1
类型转换
显示类型转化和隐式类型转换
number:将变量值转化成数字,null 可以转换成 0,true 是 1,false 是 0,但是一个是特殊的,undefined 被转换成数字类型,会输出:nan. 看起来不是数字的也是输出 nan, 如果是“123abc”也是被转换成 NaN, 不能转换成具体的数字。
parseint:把内容转换成整型的数,就是整数,输入 123.98,会直接舍去,输出 123,输入“123abc”输出“123”,parseint 有个独特的功能,从数字位开始往后看,一直看到非数字位截止,把之前的数字返回。
parsefloat:更 parseint 很相似,不同的是,float 是浮点数就是小数,如果输入内容是:“123.45abc“,会输出 123.45,它也是从数字位开始看,一直看到除了. 之外的非数字位截止,后面的做截断,返回前面的值。
string:把内容转换成字符串,
boolean:把内容转换成布尔值,输入 0 -0 null undefined nan false 以及空字符串””会输出 false, 其余的均输出 true。
tostring:想把谁转换成字符串就用谁.tostring, 有两个特殊的,undefined 和 null 不能使用 tostring 这个方法。
隐式类型转换:
isNaN()–>(调用的是 Number): 把变量拿出来,先放到 number 里面去,转换的结果再与 nan 比对,如果是 NaN 则打印出 true,如果不是则输出 false. 这个数必须是 NaN 的时候才返回 true,例如 isNaN(‘100’), 显然 100 不是 NaN, 则返回 false
++/–、+(正)-(负)(调用的是 number)
-(减号)*/% –》number(调用的也是 number)
+(加号)(调用的是 string):有一个特殊的语法,当加号两侧有一个是 string(字符串),就会调用 string 将两个全部转换成字符串。例如:var num = (1 + ‘2’); 输出的是 12,因为 + 加号已经将 1 转换成字符串“1”, 所以结果是 12.
< > <= >=(转换成 boolean):var num = 1 > “2”; 打印出 false。
==!=(调用的也是 boolean):undefined == null; 打印 true,undefine 和 null 一样,> = < 0 都会输出 false。
不发生类型转换(左右两侧长得一模一样(类型和数字)才会绝对等于,除了 NaN)
===:绝对等于
!==:绝对不等于
注意:typeof(a)返回的是字符串”undefined”, 所以 typeof 打印出的结果类型是 string。
小练习:
此处注意:NaN 不等于 NaN, 但是 undefined == null;
函数:
- 定义:function 函数名(){}函数名和变量名格式差不多,
但是命名必须符合小驼峰原则:单词首字母小写,后面单词的首字母必须大写。
- 函数组成形式:
函数名称、参数(形参、实参 arguments)、返回值。不定参数、
- 函数的作用域:(函数里面的参数,就相当于函数内部已经定义好了的变量)
Js(单线程、解释性语言)运行三部曲:
语法分析、预编译、解释执行
arguments.length 表示实参的个数,函数名.lenth 表示形参的个数。
js 预编译:
函数声明整体提升
变量 声明提升(注意只是声明提升,并不是赋值提升)
imply global:暗示全局变量,
全局对象:window
window 就是全局的域:
var a = 123;
等于先声明 var a; 再 a = 123;
console.log(a);
window 相当于仓库,是一个对象和 GO(global object)一样的功能。
任何全局变量都是 window 的属性
预编译:一切声明的全局变量(注意不包括局部变量),全是 window 的属性。
window 就是全局,
预编译发生在函数执行的前一刻:
预编译的步骤:第一步:创建 AO(activation object)对象。执行期上下文,就是理解的作用域
第二步:找函数的形参和变量声明,将变量声明的名和形参作为 AO 对象数属性名,值为 undefined
第三步:将实参值和形参值统一
第四步:在函数体里面找函数声明(定义一个变量等于函数不算函数声明(var a = function(){}),函数声明必须有函数名才可以),值赋予函数体
预编译声明的变量或者函数输出的时候,如果有自己的 AO 值,就打印输出自己拥有的 AO 的值,就近原则,而不必要打印输出 GO 就是 window 的值。
作用域:
[[scope]]; 存储了运行期上下文的集合
作用域链:scope 所存储的执行期上下文对象的集合
查找变量:从作用域链的顶端依次向下查找。
补充一点: 在哪个函数里面查找变量,就取函数的作用域链的顶端依次向下查找。
闭包:
如果内部的函数被保存到外部,它一定生成闭包。
缺点:闭包会导致原有作用域链不释放,造成内存泄漏
内存泄漏:内存占用多了,可利用的内存就少了。
闭包的作用
实现公有变量:函数累加器
可以做缓存:存储结构
可以实现封装,属性私有化
模块化开发,防止污染全局变量
闭包:内部函数在外部被调用的时候产生闭包,只有闭包才可以实现在外部调用和改变内部函数的属性
对象:
增删改查
对象创建方法:
1、var obj = {} plainObject // 对象直接量
2、构造函数创建方法
1)系统自带的构造函数 new Object()Array() Number()
2)自定义 构造函数命名的时候首字母都要大写
构造函数的内部原理(三段式)1、在函数体最前面隐式的加上 this = {}
2、执行 this.xxx = xxx;
3、隐式的返回 this
只有对象才有属性和方法,对象包括函数、数组和对象自己。
var str = new String (‘ass’)
在函数前面加了一个 new,就是一个构造函数
undefined 和 null 不可以设置属性
原始值数字不可以有属性和方法,但是对象可以有属性和方法。
原始值不能调用属性和方法
原型:function 对象的一个属性,定义了构造函数制造出的对象的公共祖先,通过该构造函数产生的对象,可以继承该原型的属性和方法,原型也是对象。
构造函数名字.prototype. 属性 = 值。
提取公有的部分写到原型内,减少代码的冗余,
object.prototype 是原型链的终端。
原型链的原理和原型差不多,增删改查也差不多
修改:如果属性有引用值的时候,就可以修改
Object.create 也可以创建对象
绝大多数对象最终都会继承自 Object.prototype,并不是所有的对象继承最终都会来自这个。
原型是系统自定义的内部属性,不可以自己添加。
只有 undefined 和 null 没有 toString 和原型
toString: 变成字符串形式,本身没有方法,要包装类
Math:ceil:向上取整:
Math:floor:向下取整:
math:random();产生 0 到 1 的开区间随机数(0,1)
toFixed(n):保存 n 位有效数字, 是保留小数点之后的有效位数为 n,如果是个整数的话,则小数点之后是两个 0
如果保留两位有效数字的时候,小数点之后的第三位数字大于等于 5 的时候就要进 1.
注意:call/apply:改变 this 指向
在企业上的实际运用就是借用别人的函数实现自己功能
call 和 apply 的区别:apply 只能传入一个实参,且必须是数组
call 和 apply 的目的是改变 this 的指向
两者的区别是传参列表不同。(call 需要把实参按照形参的个数传进去(就是实参个数 == 形参个数),apply 需要传一个 arguments 实参列表)
继承发展史.
- 原型链
- 借用构造函数
- 共享原型
- 圣杯模式
this:
- 函数预编译过程中,this 指向—> window,预编译的时候 arguments 是放在 AO 的,且还有一个 this:window,var this = Object.create(funxtion.prototype);
- 全局作用域里面:this — > window, 就是 GO 里面也有一个 this:window。
- call/apply 可以改变函数运行时 this 指向,两者的区别是传参列表不同。
- obj.func();func()里面的 this 指向 obj(谁调用的这个方法,这个方法里面的 this 就指向谁)
命名空间
管理变量,防止污染全局,适用于模板化开发
类数组:
组成部分:属性要为索引(数字)属性,必须有 length 属性,最好加上 push 方法,
属性一旦经历了 var 的操作,所得出的属性,这种属性叫做不可配置的属性。
通过 var 增加的属性,叫不可配置的,不能删除
1、预编译 this –> window
2、谁调用的 this 指向谁
3、call apply
4、全局 this –> window
- try catch
在 try 里面发生错误,不会执行 try 里面的后续代码,然后执行外面的
try 里面的代码有错的时候,后续的代码还是可以执行的
错误信息
evalError:eval()的使用与定义不一致
rangeError: 数值越界
常见的:
referenceError:(未经声明(变量、函数)就使用 is not defined)
syntaxError:语法解析错误(代码中出现中文字符)
浏览器是基于 es3 + es5 新增的方法
“use strict”,在代码最顶端加上就变成了 es5
和 es3 产生冲突的解决方案,均使用 es5 的
es5 的严格模式不能用 with
with 会把里面的对象当作 with 要执行的代码体的作用域链的最顶端
with 可以改变作用域链,with 里面的对象是 AO
with 可以简化代码
es5 规定变量赋值前必须声明
局部的 this 必须被赋值,赋值是什么就是什么
局部的 this 预编译的时候是空值,不赋值会是 undefined
es5 不可以重复属性和参数,但是不报错
eval 里面能够将字符串当作代码执行
DOM
document object model(操作 html)
对 html 的标准编程接口
dom 的基本操作:
获取键盘码:
document.onkeydown = function(e) {console.log(e.which)};
选中页面的一个元素,按键盘上面的键
键盘的操作:上 38,右 39,下 40,左 37,enter:13,空格:32,删除:8
立即执行函数:
for 循环里包含有不知道什么时候执行的函数,并且这个函数访问了 for 的循环变量,就要使用立即执行函数函数解决 i 被改变成最终值的问题
sublime 按照插件:
emmet 教程
首先安装 package control
再 preferences —-> packsge control 安装,安装完了之后打开输入 install package —-> 输入 emmet 安装 —》输入 jsprettify 安装。
dom 基础操作
document 代表整个文档
查看元素的节点:
document.getElementById
document.getElementsByTagName(比较常用)
document.getElementsByClassName
document.getElementByName 只有部分标签 name 才可以生效(表单、img、iframe)基本不用
querySelector:基本不用,选出来的元素不是实时的,
遍历树节点
parentNode -> 父节点(最顶端的 parentNode 是 #document)childNodes -> 子节点们
firstChild -> 第一个子节点
lastChild -> 最后一个子节点
nextSibling –> 后一个兄弟节点
previousSibling -> 前一个兄弟节点
节点的类型:
元素节点(1)、属性节点(2)、文本节点(3)、注释节点(8)、
基于遍历元素节点树的遍历
parentElement -> 返回当前元素的父元素节点(ie 不兼容)children -> 只返回当前元素的元素子节点(常用)node.childElementCount === node.children.length 当前元素节点的字节点
firstElementChild -> 返回第一个元素节点(ie 不兼容)lastElementChild -> 返回最后一个元素节点
前一个兄弟元素节点:nextElementSibling:
最后一个兄弟元素节点
lastElementSibling
节点的四个属性:
nodeName:元素的标签名,以大写的形式表示只读
nodeValue:文本或者注释 comment 节点的属性,可以读写
nodeType:只读,不可写入(任何元素都有这样一个属性)
attributes:element 节点的属性节点的结合(能够赋值和修改)
节点的一个方法:Node.hasChildNodes()有没有子节点,代表一个函数方法,所以必须要加括号
类数组加一个 splice:Array.prototype.splice 之后就是一个数组
Document 可以理解成构造函数,document 代表整个文档
两者之间是逐步继承的关系
document –- > HTMLDocument — >Document.prototype
HTMLDocument.prototype {_proto_:Document}
document 上面有两个直接的属性,一个是 body 一个是 head
document.documentElement — > 指的就是 html
JS 三个组成部分
ecmascript dom bom
基于元素节点树的遍历,除了 children 之外,兼容性比较差
构造函数都有一个原型
dom 结构树,一系列的继承关系
就近继承
date 对象
var date = new Date()
date.getTime(), 距 1970 年 1 月 1 日的毫秒
setInterval 是非常不准的,定时器,是 window 上面的一个方法
setTimeout 只执行一次
查看视口的尺寸
window.innerWidth/innerHeight(加上 滚动条宽度 / 高度)IE8 及 IE8 以下不兼容
document.documentElement.clientWidth/clientHeight
标准模式下,任意浏览器都兼容
document.body.clientWidth/clientHeight
适用于怪异模式下的浏览器
封装兼容性方法,返回浏览器视口尺寸 getViewportOffset()
查看元素的位置
dom.offsetLeft, dom.offsetTop
对于无定位父级的元素,返回相对文档的坐标。对于有定位父级的元素,返回相对于最近的有定位的父级的坐标。(无论是 left 还是 margin-left 等都是距离。)
position 的默认值:static
dom.offsetParent
返回最近的有定位的父级,如无,返回 body, body.offsetParent 返回 null
emmet:
ul>li{$}*5
____滚动条在 y 轴上滚动的距离 + 浏览器的视窗高度 = 文档的总高度
当:滚动条在 y 轴上滚动的距离 + 浏览器的视窗高度 = 文档的总高度
说明:已经滚动到底部 __
查看视口的尺寸
window.innerWidth/innerHeight(加上 滚动条宽度 / 高度)IE8 及 IE8 以下不兼容
document.documentElement.clientWidth/clientHeight
标准模式下,任意浏览器都兼容
document.body.clientWidth/clientHeight
适用于怪异模式下的浏览器
封装兼容性方法,返回浏览器视口尺寸 getViewportOffset()
脚本化 css
特殊的:eg:float — > cssFloat
复合属性必须拆解
查询计算样式
window.getComputesStyle(elem, null);
var style = window.getComputedStyle(div, null);
// 第二个参数是 null
// 选择伪元素
// null 可以获取伪元素
选择 after 的伪元素
改变伪元素
`
var after = window.getComputedStyle(div, 'after');`
定位的 left 和 top 默认值为 auto
事件:
事件触发的过程和函数
如何绑定事件处理函数
- ele.onxxx = function (event) {}
兼容性很好,但是一个元素只能绑定一个处理程序,属性赋值会被覆盖
基本等同于写在 HTML 行间上,
- ele.addEventListener(type 事件类型, fn 处理函数, false);
IE9 以下不兼容,可以为一个事件绑定多个处理程序
- ele.attachEvent(‘on’+ type, fn);
IE 独有,一个事件同样可以绑定多个处理程序
一但事件出现了循环,就要考虑是否出现闭包,就要使用立即执行函数
事件处理程序的运行环境问题
- ele.onxxx = function (event) {}
程序 this 指向是 dom 元素本身
- obj.addEventListener(type, fn, false);
程序 this 指向是 dom 元素本身
- obj.attachEvent(‘on’+ type, fn);
程序 this 指向 window
封装兼容性的 addEvent(elem, type, handle); 方法
解除事件处理程序
ele.onclick = false/‘’/null;
ele.removeEventListener(type, fn, false);
ele.detachEvent(‘on’+ type, fn);
注: 若绑定匿名函数,则无法解除
事件冒泡:
结构上(非视觉上)嵌套关系的元素,会存在事件冒泡的功能,急同一个事件,自子元素冒泡向父元素(自底向上)
事件捕获:
结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,急同一个事件,自子元素捕获至子元素(自底向下)
如果同时存在冒泡和捕获的时候:
触发顺序,先捕获,后冒泡
focus(聚焦事件),blur,change,submit,reset,select 等事件不冒泡
取消冒泡:
W3C 标准 event.stopPropagation(); 但不支持 ie9 以下版本
IE 独有 event.cancelBubble = true;
封装取消冒泡的函数 stopBubble(event)
阻止默认事件:
默认事件 — 表单提交,a 标签跳转,右键菜单等
1.return false; 以对象属性的方式注册的事件才生效(兼容性很好)2.event.preventDefault(); W3C 标注,IE9 以下不兼容
3.event.returnValue = false; 兼容 IE
封装阻止默认事件的函数 cancelHandler(event);
事件源对象:
`
var target = event.target || event.srcElement`
作用:不需要循环所有的元素一个个绑定事件,当有新的子元素的时候,不需要重新绑定所有的事件
鼠标事件:click、mousedown、mousemove(鼠标移动事件)、mouseup、contextmenu(右键取消菜单)、mouseover、mouseout、mouseenter、mouseleave(效果是一样的)html5 里面是写的 enter 和 leave
用 button 来区分鼠标的按键,0/1/2
onclick = onmousedown + onmouseup
顺序:down、up、click
用 button 判断当前点击的是鼠标左键还是右键
button == 0 表示鼠标左键
button == 2 表示鼠标右键
dom3 标准规定,click 只能监听左键,不能监听右键,能监听的只有 onmousedown 和 onmouseup。
js 加载时间线:
执行顺序
1、创建 Document 对象,开始解析 web 页面。解析 HTML 元素和他们的文本内容后添加 Element 对象和 Text 节点到文档中。这个阶段 document.readyState = 'loading'。2、遇到 link 外部 css,创建线程加载,并继续解析文档。3、遇到 script 外部 js,并且没有设置 async、defer,浏览器加载,并阻塞,等待 js 加载完成并执行该脚本,然后继续解析文档。4、遇到 script 外部 js,并且设置有 async、defer,浏览器创建线程加载,并继续解析文档。对于 async 属性的脚本,脚本加载完成后立即执行。(异步禁止使用 document.write())5、遇到 img 等,先正常解析 dom 结构,然后浏览器异步加载 src,并继续解析文档。6、当文档解析完成,document.readyState = 'interactive'。7、文档解析完成后,所有设置有 defer 的脚本会按照顺序执行。(注意与 async 的不同, 但同样禁止使用 document.write(),有消除文档流的功能);
8、document 对象触发 DOMContentLoaded 事件,这也标志着程序执行从同步脚本执行阶段,转化为事件驱动阶段。9、当所有 async 的脚本加载完成并执行后、img 等加载完成后,document.readyState = 'complete',window 对象触发 load 事件。10、从此,以异步响应方式处理用户输入、网络事件等。
js 正则表达式
RegExp
转义字符 \
正常情况下:一个回车代表 \r\n
正则表达式作用:匹配特殊字符或有特殊搭配原则的字符的最佳选择。正则表达式创建方法:正则表达式的三个修饰符:I 忽视大小写
g 全局匹配
m 多行匹配(.
正则表达式的方法:test 和字符串上面的方法 match,字符串.match(正则表达式)
[参考手册]
(http://www.w3school.com.cn/js…
正则表达式的 exec()方法:
reg.exec();