JS 语法
Javascript 由三部分组成
-
ECMAScript
(前身为欧洲计算机制造商协会) ,JavaScript的语法规范,提供核心语言功能
- WEB浏览器只是ECMA的宿主环境之一,也可以不依赖浏览器,比如宿主环境可能还包括Node和Adobe Flash; ECMAScript规定了Javascript这门语言的组成部分;主要规定了语法、类型、语句、关键字、保留字、操作符、对象
-
DOM
(文档对象模型 Document Object Model 的简称),JavaScript操作网页上元素的API- DOM把整浏览器页面映射为一个多层节点结构,页面中每个组成部分都是某种类型的节点,这些节点又包含了不同类型的数据
-
BOM
(浏览器对象模型 Browser Object Model 的简称),JavaScript操作浏览器部分功能的API
数据类型
- 简单数据类型(值类型)
字符串 数字 布尔 未定义 空
String Number Boolean undefined null - 复杂数据类型
Object、function、Array、Date、RegExp、Error.......
简单数据类型介绍
- Number
NaN 非数值(Not a Number的简写)
console.log(“abc”/18); //结果是NaN
Undefined和任何数值计算为NaN;
NaN 与任何值都不相等,包括 NaN 本身 - Booblean
true、除0数字、“something”、Object(任何对象)为true
false、0 、“”、undefined 、null为false - undefined和null的
- 逻辑上
null
表示一个空对象的指针,使用typeof检测的时候会返回object;(object原型的终点也是null) -
undefined
使用var声明变量但没有初始化,区分空对象指针与尚未定义的变量,对未初始化的变量以及未声明的变量使用,typeof运算符均会返回undefined -
null
和undefined
有最大的相似性: 看看null == undefined的结果(true)也就更加能说明这点。但是null ===undefined的结果(false)。不过相似归相似,还是有区别的,就是和数字运算时,10 + null结果为:10;10 + undefined结果为:NaN。
任何数据类型和undefined运算都是NaN;
任何值和null运算,null可看做0运算。
- 逻辑上
数据类型转换
var num1 = Number(“18”); // 有非数字字符会出现NaN
parseInt() 和 parseFloat()(译为取整和取浮点数)
var bool = Boolean(“1111”); // bool为true;
数组的操作
// Instanceof: 是一个关键字。 判断A是否是B类型。
布尔类型值 = A Instanceof B ;
//HTML5中新增 判断是不是数组
Array.isArray()
// 把别的类型数据,转为字符串
// 把Array转换成字符串,每一项用,分割
// null和undefined没有toString方法,所以转换的时候用String()函数
toString()
//返回数组对象本身
valueOf()
// 根据每个字符把数组元素连起来变成字符串, 变量可以有可以没有。不写默认用逗号分隔,无缝连接用空字符串
字符串 = 数组.join(变量);
//在数组最后面插入项,返回数组的长度
push()
//删除数组中的最后一项,返回最后一项
//被删除的元素 = 数组1.pop();
pop()
//在数组最前面插入项,返回数组的长度
unshift()
//删除数组中的第一个元素,返回被删除的元素
shift()
//翻转数组
reverse()
//给数组排序,返回排序后的数组。如何排序看参数
sort();
从小到大排序后的数组 = 数组1.sort(function(a,b) {
return a-b;
});
//把参数拼接到当前数组
// concat()
新数组 = 数组1.concat(数组2);
//从当前数组中截取一个新的数组,不影响原来的数组,参数start从0开始,end从1开始
slice()
新数组 = 数组1.slice(索引1,索引2);
//删除或替换当前数组的某些项目,参数
splice()
start,deleteCount,options(要替换的项目)
新数组 = 数组1.splice(起始索引,结束索引,替换内容);
//如果没找到返回-1
indexOf()、lastIndexOf()
DOM 操作
DOM访问关系
- 父节点 (parentNode )
- 兄弟节点
-
nextElementSibling
:在火狐谷歌IE9都指的是下一个元素节点。
下一个兄弟节点=节点.nextElementSibling || 节点.nextSibling -
previousElementSibling
:在火狐谷歌IE9都指的是前一个元素节点。
下一个兄弟节点=节点.previousElementSibling|| 节点.previousSibling
-
- 单个子节点
-
firstElementChild
: 在火狐谷歌IE9都指的第一个元素节点。 -
lastElementChild
:在火狐谷歌IE9都指的最后一个元素节点
-
- 所有子节点
-
childNodes
:它是标准属性,它返回指定元素的子元素集合,包括HTML节点,所有属性,文本节点 (他还是W3C的亲儿子 )
// nodeType == 1 表示的是元素节点 记住 元素就是标签
// nodeType == 2 表示是属性节点 了解
// nodeType == 3 是文本节点 了解
子节点数组 = 父节点.childNodes; 获取所有节点。 -
children
:非标准属性,它返回指定元素的子元素集合。
但它只返回HTML节点,甚至不返回文本节点,虽然不是标准的DOM属性,但它和innerHTML方法一样,得到了几乎所有浏览器的支持。
children在IE6/7/8中包含注释节点
在IE678中,注释节点不要写在里面。
子节点数组 = 父节点.children; // 用的最多。
-
DOM节点操作(重点)
- 创建节点
新的标签(节点) = document.createElement(“标签名”); - 插入节点(使用节点)
// 父节点的最后插入一个新节点
父节点.appendChild(新节点);
// 在参考节点前插入
父节点.insertBefore(新节点,参考节点); - 删除节点
// 必须指定要删除的子节点
父节点.removeChild(子节点); - 复制节点
// 参数可选复制节点
// 方法内部可以传参,入股是true,深层复制,如果是false,只复制节点本身。
新节点=要复制的节点.cloneNode(参数) ; - 节点属性
// 注意:IE6、7不支持。
获取:getAttribute(名称)
设置:setAttribute(名称, 值)
删除:removeAttribute(名称)
DOM 属性操作
正则
正则的组成
每一个正则表达式都是由元字符和修饰符组成的
什么是[元字符]:在//之间具有意义的一些字符
具有特殊意义的元字符
-
:
转义字符,转译后面字符所代表的含义 -
^
: 以某一个元字符开始 -
$
: 以某一个元字符结尾 -
\n
: 匹配一个换行符 -
.
: 除了\n以外的任意一个字符
var reg = /^0.2$/;//->以0开头,以2结尾,中间可以是除了\n的任意一个字符
console.log(reg.test("0.2"));//->true
console.log(reg.test("0-2"));//->true
console.log(reg.test("0s-2"));//->false
//
reg = /^0.2$/;//->以0开头,以2结尾,中间是.的字符串;
console.log(reg.test("0.2"));//->true
console.log(reg.test("0-2"));//->false
- `()`: 功能一:分组 ->把一个大正则本身划分成几个小的正则
- ```
var reg1 = /^\d+zhu\d+$/;
var reg2 = /^(\d+)zhu(\d+)$/;
//匹配
console.log(reg1.test("2zhu3"));//true
console.log(reg2.test("2zhu4"));//true
//捕获
console.log(reg1.exec("2zhu3"));//["2zhu3", index: 0, input: "2zhu3"]
console.log(reg2.exec("2zhu4"));//["2zhu4", "2", "4", index: 0, input: "2zhu4"]
-
x|y
: x或者y中的一个 -
^x|yz$
: x开头、yz结尾、x开头并且yz结尾、三种都可以 -
[xyz]
: x或者y或者z中的一个 -
[^xyz]
: 除了三个以外的任何一个字符 -
[a-z]
: a-z之间的任何一个字符 -
[^a-z]
: 除了a-z之间的任何一个字符 -
\d
: 一个0-9之间的数字\D
: 除了0-9之间的数字以外的任何字符 -
\b
: 匹配一个边界符 -
\w
: 数字、字母、下划线中的任意一个字符,等于[0-9a-zA-Z_]
-
\s
: 匹配一个空白字符 空格、一个制表符、换页符...
代表出现次数的量词元字符
-
*
: 出现零到多次 -
+
: 出现一到多次 -
?
: 出现零次或者一次 -
{n}
: 出现n次 -
{n,}
: 出现n到多次 -
{n,m}
: 出现n到m次
var reg = /^\d+$/;
console.log(reg.test("2015"));//->true
// 一个简单的验证手机号的正则:11位数字,第一位是1
var reg = /^1[3|4|5|7|8]\d{9}$/;//第一位以1开始,第二位可以是34578中的任意一位,后面再加9个数字;
console.log(reg.test("12345678901"));//false
console.log(reg.test("13856487589"));//true
console.log(reg.test("12114567895"));//false
####元字符的应用
#####`[]`整括号的注意
- 在整括号中出现的所有的字符都是代表本身意思的字符(没有特殊的含义,\d这种特殊)
- ```
// 以 . 开头,后面跟上至少一个数字
var reg = /^[.]\d+$/;
console.log(reg.test("46545"));//->false
console.log(reg.test(".89"));//->true
// 以 . 开头,中间至少一个数字,以 + 结尾
var reg1 = /^[.]\d+[+]$/;
console.log(reg1.test("46545"));//->false
console.log(reg1.test(".89+"));//->true
//
var reg2 = /^[.]\d+0[\d+]$/;
console.log(reg2.test("46545"));//->false
console.log(reg2.test(".465045"));//->true 如果是465045就是false
console.log(reg2.test(".890+"));//->true
-
[]
整括号中不识别两位数,整括号内是多个取一个
var reg1 = /^[12]$/;//->1或者2中的一个
console.log(reg1.test("12"));//false
console.log(reg1.test("1"));//true
console.log(reg1.test("2"));//true
// 1、2-6中的一个、8 三个中的一个
var reg2 = /^[12-68]$/;
console.log(reg2.test("128"));//false
console.log(reg2.test("138"));//false
console.log(reg2.test("158"));//false
console.log(reg2.test("1"));//true
console.log(reg2.test("3"));//true
console.log(reg2.test("5"));//true
console.log(reg2.test("8"));//true
console.log(reg2.test("13"));//false
//
var reg = /^[\w-]$/;//->数字、字母、下划线、- 中的一个
console.log(reg.test("-"));//true
console.log(reg.test("89"));//false
console.log(reg.test("_"));//true
######()整括号的另外作用:改变x|y的默认的优先级
- |的优先级很高;
- 功能:替换,"或"操作字符具有高于替换运算符的优先级,使得"m|food"匹配"m"或"food"。若要匹配"mood"或"food",请使用括号创建子表达式,从而产生"(m|f)ood"。
var reg1 = /^18|19$/;
//错误分析:想匹配119和189,1开始,9结尾,中间是8或者1的任意一个;
//实际可以这些数字都是可以匹配成功的:18、19、181、189、119、819、1819...
console.log(reg1.test("19"));//true
console.log(reg1.test("18"));//true
console.log(reg1.test("119"));//true
console.log(reg1.test("189"));//true
console.log("test 189999999999",reg1.test("189999999999"));//true
console.log("test 819",reg1.test("819"));//true
console.log("test 1819",reg1.test("1819"));//true
console.log("test 1889899819",reg1.test("1889899819 "));//true
//正确分析:18|19 可以匹配18开头或者19结尾的;(18开头)、(19结尾)、(18开头和19几位的),都可以匹配成功;
//|替换,"或"操作字符具有高于替换运算符的优先级,使得"m|food"匹配"m"或"food"。若要匹配"mood"或"food",请使用括号创建子表达式,从而产生"(m|f)ood"。
var testReg1=/m|food/;
//匹配(m开头)、(food结尾)、(m开头或者food结尾);这三种都可以匹配
console.log("test m",testReg1.test("m"));//true
console.log("test m464545646565",testReg1.test("m464545646565"));//true
console.log("test mood",testReg1.test("mood"));//true
console.log("test food",testReg1.test("food"));//true
var testReg2=/(m|f)ood/;
//匹配mood/food
console.log("test m",testReg2.test("m"));//false
console.log("test m464545646565",testReg2.test("m464545646565"));//false
console.log("test mood",testReg2.test("mood"));//true
console.log("test food",testReg2.test("food"));//true
var reg2 = /^(18|19)$/;
//18、19
console.log(reg2.test("19"));//true
console.log(reg2.test("18"));//true
console.log(reg2.test("119"));//false
console.log(reg2.test("189"));//false
var reg3 = /^1[8|1]9$/;
//119、189
console.log("test 19",reg3.test("19"));//false
console.log(reg3.test("18"));//false
console.log(reg3.test("119"));//true
console.log(reg3.test("189"));//true
---
###正则实践
- 有效数字的正则(可以是 正数、负数、零、小数 )
1)、"."可以出现也可以不出现,但是一旦出现,后面必须跟着一位或者多位数字
2)、最开始可以有+/- 也可以没有
3)、整数部分,一位数可以是0-9之间的一个,多位数不能以0开头
var reg = /^[+-]?(\d|([1-9]\d+))(.\d+)?$/;//.是一个元字符,所以需要转义;
- 年龄介于18~65之间
18~65可以分为三份;18-19 20-59 60-65
因为1开头的不能是12,15,14这些;
6开头的不能是66,68这些;
2和5开头,后面可以随便,0-9都可以;
var reg = /^(1[8-9]|[2-5]\d|6[0-5])$/;
- 验证邮箱的正则(简版)
左边:数字、字母、下环线、.、-
\w:数字、字母、下划线中的任意一个字符 [0-9a-zA-Z_]
[\w.-]:[\w]、[.]、[-]三者中的任意一个,出现一次或者多次;
[0-9a-zA-Z]:大小写,或者数字;
(.[a-zA-Z]{2,4}) .后面加2-4位大小写的域名,比如.com .cn
{1,2} 出现一次或者两次。可能是顶级域名,也可能是二级域名;
var reg = /^[\w.-]+@[0-9a-zA-Z]+(.[a-zA-Z]{2,4}){1,2}$/;