JavaScript基础笔记
常用
控制浏览器弹出一个警告框
alert("it is my first js code");
让浏览器在页面中输出一个内容(向body中输出一个内容)
document.write("something from document");
向控制台输出一个内容
console.log("guess what?");
控制浏览器弹出一个带有确认和取消的提示框
var flag = confirm("Are you sure?")
需要一个字符串作为参数, 该字符串会作为提示文字显示
若用户单机确认则返回true, 否则返回false
prompt()
显示可提示用户输入的对话框
代码编写的位置
外部
可以将js代码编写在外部js文件中, 然后通过script标签引入
<script type="text/javascript" src="js/script.js>
- 可以在不同的页面中同时引用, 也可以利用浏览器的缓存机制
- 开发时推荐使用的方式
内部
可以将js代码写到script标签中
可以将js代码编写到标签的onclick属性中,当点击按钮时 js代码才会执行
- 属于结构与行为耦合, 不方便维护, 不推荐使用
可以将js代码写在超链接的href属性中, 当点击超链接时, 会执行js代码
click
click
基本语法
js中严格区分大小写
js中每一条语句以分号(;)结尾, 如果不写分号, 浏览器会自动添加, 但是会消耗系统资源, 并且有加错分号的可能性
js中会忽略多个空格和换行, 所以可以利用空格和换行对代码进行格式化
字面量
都是一些不可改变的量(如: 1 2 3 4 )
数据类型
- String 字符串 string
- \" 表示 "
- \' 表示 '
- \n 表示换行
- \t 表示制表符
- \\ 表示 \
- 引号不能嵌套, 双引号里不能放双引号, 单引号里不能放单引号
- 在JS中需要使用引号引起来(使用双引号或单引号都可, 但是不要混在一起用)
- 在字符串中可以使用\作为转义字符, 当表示一些特殊符号时可以使用\进行转义
- Number 数值 number
- 数据类型为number
- Infinity 表示正无穷
- -Infinity 表示负无穷
- 数据类型为number
- 在JS中所有数值都是Number类型, 包括整数和浮点数
- Number.MAX_VALUE = 1.796931348623157e+138
- Number.MIN_VALUE = 5e-324
- 如果使用Number表示的数字超过了最大值, 则会返回一个Infinity
- NaN 是一个特殊的数字, 表示Not A Number
- 在JS中的整数运算基本可以保证精确, 如果使用JS进行浮点运算, 可能得到一个不精确的结果(不要使用JS进行精确度要求较高的运算)
- 在JS中, 如果需要表示16进制的数字, 需要以0x开头, 如果需要表示8进制的数字, 则需要以0开头, 如果需要表示2进制的数字, 则需要以0b开头, 但不是所有的浏览器都支持
- Boolean 布尔值 boolean
- Null 空值 object
- Undefined 未定义 undefined
- Object 对象 object
其中String Number Boolean Null Undefined属于基本数据类型, Object属于引用数据类型
typeof
可以使用运算符typeof来检查变量的类型
typeof 变量名
检查字符串时 会返回string
检查数值时 会返回number
变量
可以用于保存字面量, 并且可以任意改变
- 变量更加方便使用, 在开发中一般通过变量来保存字面量, 而很少直接使用自变量
- 在js中使用var来声明一个变量
标识符
- 在js中所有可以由我们自主命名的都可以称作标识符
- 例如: 变量名, 函数名, 属性名
- 命名标识符要遵守的规则:
- 标识符中可以含有字母, 数字, _, $
- 标识符不能以数字开头
- 标识符不能是ES中的关键字或保留字
- 标识符一般采用驼峰命名法(首字母小写, 每个单词的首字母大写, 其他字母小写)
- JS底层保存标识符时实际上是采用Unicode编码(utf-8)
强制类型转换
指将一个数据类型强制转换为其他的数据类型
其他数据类型转换为String
toString()
调用被转换数据类型的toString()方法
该方法不会影响到原变量, 它会将转换的结果返回
Null和Undefined这两个值没有toString()方法
String()
调用String()函数, 并将被转换的数据作为参数
对Number Boolean实际上就是调用toString()方法
但对于null和undefined, 就不会调用toString()方法
它会将null转换为"null", undefined转换为 "undefined"
其他数据类型转换为Number
Number()
- true 转为1
- false 转为0
- 如果是纯数字字符串, 则直接转换为数字
- 如果字符串中有非数字内容, 则转换为NaN
- 3.如果字符串为空串或全是空格, 则转换为0
字符串 --> 数字
布尔 --> 数字
Null --> 数字 0
Undefined --> 数字 NaN
parseInt()&parseFloat()
可以通过在parseInt()中传递第二个参数, 用于指定进制
parseInt(a, 10)
专门用于字符串
parseInt() 把一个字符串中有效的整数内容取出, 并转换为整数
parseFloat() 和parseInt()类似, 不同的是可以获得有效的小数
对"070"这种字符串, 有些浏览器会当成八进制解析, 有些会当成十进制
对非String使用以上函数, 会先将其转换为String, 再进行操作
将其他数据类型转换为Boolean
使用Boolean()函数
数字 -- > 布尔 除了0和NaN, 其余的都是true
字符串 --> 布尔 除了空串, 其余的都是true
null 和 undefined都是false
运算符
逻辑运算符
&&运算
- 如果两个值中有false, 返回靠前的false
- 如果第一个值为true, 则返回第二个值
||运算
- 如果第一个值为true, 返回靠前的false
- 如果第一个值为false, 返回第二个值
关系运算符
- 数字与非数字的符号进行关系运算时, 将其转换为数字再进行运算
- 任何值与NaN进行关系运算时, 一律返回false
- 若符号两侧都是字符串, 不会将其转换为数字比较, 而是分别比较字符串中字符的Unicode编码, 如果两位一样, 则比较下一位, 直到有大小区别, 可以借用它对英文字符进行排序
- 比较中文字符时没有意义
Unicode编码
在字符串中使用转义字符输入Unicode编码
\u四位数编码
在网页中使用Unicode编码
&#编码(十进制)
相等运算符
==
- 可以通过isNaN()函数来判断一个值是否是NaN
- 如果两边值的类型不同,则自动进行类型转换再进行比较
- undefined延伸值null 所以两个做相等运算时返回true
- NaN不和任何值相等, 包括其本身
!=
- 规则与==类似
===
- 用于判断两个值是否全等,不会做自动的类型转换
- 不同类型的值进行比较直接返回false
!==
- 类似于!=,不进行自动类型转换
,运算符
- 可以用于分割多个语句, 一般在声明多个变量时使用
运算优先级
- 如果不清楚符号的优先级,可以使用()改变优先级
代码块
- 用{}为语句进行分组,同一个{}中的语句要么都执行, 要么都不执行
- JS中的代码块只有分组作用, 在外部是完全可见的
语句
流程控制语句
条件判断语句(if)
条件分支语句(switch)
switch(条件表达式){ case 表达式: 语句; ... break; default: 语句; ... break; }
循环语句
while语句
//先判定再执行 while(条件表达式){ 循环主体; }
//先执行一次再判定 do{ 循环主体; }while(条件表达式)
for语句
函数
函数是一个对象
函数中可以封装一些功能, 在需要时可以执行这些功能
函数中可以保存一些代码在需要的时候调用
使用typeof检查函数对象时, 会返回function
封装到函数中的代码不会立即执行, 而是在被调用时执行
函数对象();
创建函数
构造函数
- 实际开发中很少使用构造函数来创建一个函数对象
//创建一个函数对象 //可以将要封装的代码以字符串形式传递给构造函数 var fun = new Function("console.log('这是一个函数');"); //调用函数 fun();
函数声明
使用函数声明来创建一个函数
//声明函数 function 函数名([形参1, 形参2, ...形参N]){ 函数语句; } //调用函数 函数名(实参1, 实参2, ... 实参N);
使用函数表达式创建一个函数
相当于创建一个匿名函数, 再将该匿名函数赋值给变量
var 函数名 = function([形参1, 形参2, ...形参N]){ 函数语句; }; //匿名函数 function([形参1, 形参2, ...形参N]){ 函数语句; }; //调用函数 函数名(实参1, 实参2, ... 实参N);
调用函数时, 解析器不会检查实参的类型, 所以要注意是否有可能接收到非法的参数, 如果有可能, 则需要对参数进行类型检查
调用函数时, 解析器不会检查实参的数量
- 多余实参不会被赋值
- 缺少的实参将是undefined
函数的实参可以是任意的数据类型(包括对象)
当参数过多时, 可以将参数封装到一个对象中, 然后通过对象传递参数
var obj = { 属性1: ..., 属性2: ..., 属性3: ... }; function fun(o){ console.log(o.属性1 + "" + o.属性2 + "" + ...); } fun(obj);
实参可以是一个函数
函数名1(函数名2);
//将一个匿名函数作为参数传递给一个函数 函数名(function(){ 函数语句; });
函数的返回值
return 返回值
- 在return后的语句都不会执行
- 若return后不接任何值或无return语句, 则相当于返回undefined
立即执行函数
- 函数定义完, 立即被调用
- 立即执行函数往往只会执行一次
(function(形参1, ..., 形参N){ 函数语句; ... })(实参1, ..., 实参N);
函数的方法
call()和apply()是函数对象的方法, 需要通过函数对象来调用
函数名.call() 函数名.apply()
当对函数调用call()和apply()都会调用函数执行
在调用call()和apply()可以将一个对象指定为第一个参数, 此时这个对象将会成为函数执行时的this
call()方法可以将实参在对象之后依次传递
apply()方法需要将实参封装到一个数组中统一传递
arguments
- 在调用函数时, 浏览器每次都会传递两个隐含的参数:
- 函数的上下文对象this
- 封装实参的对象 arguments
arguments是一个类数组对象, 它也可以通过索引操作数据, 也可以获取长度
在调用函数时, 我们所传递的实参都会在arguments中保存
arguments.length可以用来获取实参的长度
即使不定义形参, 也可以通过arguments获取实参, 但较麻烦arguments[索引]
arguments有一个属性callee, 对应一个函数对象, 计算当前正在执行的函数对象
对象(object)
对象的分类
1. 内建对象
- 由ES标准中定义的对象, 在任何ES的实现中都可以使用
- 比如, Math String Number Boolean Function Object
2. 宿主对象
- 由JS的运行环境提供的对象, 目前来讲主要指由浏览器提供的对象
- 比如BOM DOM
3. 自定义对象
- 开发者自己创建的对象
自定义对象
对象操作
创建对象
var obj = new Object(); //new关键字调用的函数, 是构造函数的constructor //构造函数是专门用来创建对象的函数
在对象中添加新的属性
对象.属性名 = 属性值
读取对象中的属性
对象.属性
如果读取对象中没有的属性, 不会报错而是会返回undefined
修改对象的属性
同添加操作
删除对象的属性
delete 对象.属性名
对象的属性
属性名
对象的属性名不强制要求遵守标识符的规范(什么名字都可以使用)
开发时应尽量按照标识符的规范做
如果要使用特殊的属性名, 不能采用.的方式来操作
需要使用另一种方式:
对象["属性名"] = 属性值
读取时也需要采用这种方式
使用[]操作属性, 更加灵活
在[]中可以直接传递一个变量
属性值
可以是任意的数据类型(包括对象)
检查一个对象(或其原型)中是否含有指定的属性
"属性名" in 对象
检查对象自身是否含有指定的属性
对象.hasOwnProperty("属性名")
对象的属性值可以是函数
当函数作为对象的属性时, 称这个函数是这个对象的方法, 调用函数称为调用这个对象的方法(method)
枚举对象的属性
使用for ... in 语句, 对象中有几个属性, 循环体就执行几次
每次执行时, 会将对象中的一个属性名赋值给变量
for(var 变量 in 对象){ //输出属性名 console.log("属性名: " + 变量); //输出属性值 console.log("属性值: " + 对象[变量]) }
对象的字面量
使用对象字面量来创建一个对象
var 对象 = { 属性名: 属性值, 属性名: 属性值, ... }
可以在创建对象时, 直接指定对象中的属性
属性名和属性值是一组一组的名值对结构, 使用冒号(???? 连接
工厂方法创建对象
function createObject(形参1, 形参2, ..., 形参N){ //创建对象 var obj = new Object(); //向对象中添加属性 obj.属性1 = 形参1; .... obj.方法 = function(){ ...; } return obj; } var obj = createObject(实参1, 实参2, ..., 实参N);
- 使用工厂方法创建的对象, 使用的构造函数都是Object, 因此创建的对象都是object类型, 导致无法区分多种不同类型的对象
- 开发中较少使用
原型(prototype)
每创建一个函数, 解析器都会向函数中添加一个属性prototype
prototype对应着一个对象, 这个对象就是原型对象
如果函数作为普通函数调用prototype没有任何作用
当函数以构造函数的形式调用时, 所创建的对象都有一个隐含的属性, 指向该构造函数的原型对象, 可以使用__proto__来访问该属性
相当于一个公共的区域, 所有同一个类的实例都可以访问到这个原型对象, 可以将对象中共有的内容统一设置在原型对象中
//向类的原型中添加一个属性 类名.prototype.属性名 = 属性值; //向类的原型中添加一个方法 类名.prototype.方法名 = function(){ ...; };
当我们访问对象的一个属性或方法时, 它会优先在对象自身中寻找, 没有则在原型中寻找, 若原型中没有, 则在原型的原型中寻找, 直到找到Object对象的原型, 若依然没有则返回undefined
创建构造函数时, 可以将这些对象共有的属性和方法统一添加在原型对象中
原型对象也是对象, 也有原型
构造函数
- 构造函数是普通的函数, 创建方式和普通函数没有区别
- 构造函数的函数名习惯首字母大写
- 调用构造函数需要使用new关键字调用
- 使用同一个构造函数创建的对象, 称为一类对象(也称为该类的实例), 也将一个构造函数称为一个类
构造函数的执行流程
- 立即创建一个新的对象
- 将新建的对象设置为函数中的this
- 逐行执行函数中的代码
- 将新的对象作为返回值返回
//向类的原型中添加共有属性 类名.prototype.属性名 = 属性值; //向类的原型中添加共有方法 类名.prototype.方法名 = function(){ ...; }; function 类名(){ this.属性名 = ...; } var obj = new 类名();
instanceof
用于检查一个对象是否是一个类的实例
对象 instanceof 类
- 所有对象都是Object的实例
toString()
- 当我们直接在页面中打印一个对象时, 输出的是对象的toString()方法的返回值
- 如果希望在输出对象时不输出[Object Object], 则可以修改对象原型的toString()方法
垃圾回收
- 当一个对象没有任何变量或属性对它进行引用, 此时我们将永远无法操作该对象, 此时这种对象就是垃圾, 这种垃圾过多会占用大量内存空间, 导致程序运行变慢, 必须进行清理
- JS中拥有自动的垃圾回收机制, 会自动将这些垃圾对象从内存中销毁, 不需要也不能进行垃圾回收的操作
- 我们需要做的只是将不再使用的对象设置为null
内建对象
Array
- 使用数字作为索引(从0开始的整数)操作元素
- 数组中的元素可以是任意数据类型
数组操作
创建数组对象
var 数组名 = new Array();
var 数组名 = [元素1, 元素2, ..., 元素n];
var 数组名 = new Array(元素1, 元素2, ..., 元素n);
var 数组名 = new Array(长度)
向数组中添加元素
数组名[索引] = 值;
尽量不要创建非连续的数组
读取数组中的元素
数组名[索引]
如果读取不存在的索引, 不会报错而是返回undefined
获取数组长度
数组名.length
对于非连续数组, 会返回 最大索引+1
修改数组长度
数组名.length(长度);
若修改的长度大于原长, 则多余部分空出来
若修改长度小于原厂, 则多余元素被删除
向数组最后一位添加元素
数组名[数组名.length] = 元素;
数组名.push(元素1, 元素2, ..., 元素n);
push()方法的返回值为数组最新的长度
删除数组的最后一个元素
数组名.pop()
返回值为被删除的元素
向数组的开头添加元素
数组名.unshift(元素1, 元素2, ..., 元素n);
返回值为数组最新的长度
删除数组的第一个元素
数组名.shift()
返回值为被删除的元素
数组功能
forEach()
数组名.forEach(function(value, index, obj){ ...; });
- 第一个参数: 当前正在遍历的元素
- 第二个参数: 当前正在遍历的元素的索引
- 第三个参数: 正在遍历的数组
- 只支持IE8以上的浏览器
- 需要一个函数作为参数
- 这种由我们创建但不由我们调用的函数被称为回调函数
- 数组中有几个元素就会执行几次, 每次执行时, 浏览器会将遍历到的元素以实参的形式传递进来
- 浏览器会在回调函数中传递三个参数:
slice()
数组名.slice(start, end)
- 从数组中提取指定元素, 参数为开始和结束位置的索引
- 返回的数组包括开始索引, 不包括结束索引
- end参数可以省略不写, 此时截取从开始索引以后的所有元素
- 索引可以传递负值, 若传递负值则从后往前计算
- 该方法不会改变原数组, 而是将截取到的部分封装到新的数组中返回
splice()
数组名.splice()
- 第一个, 表示开始位置的索引
- 第二个, 表示删除元素的数量
- 第三个及以后, 会自动插入到开始位置索引的前面
- 可用于删除数组中的指定元素并作为返回值返回
- 参数:
concat()
数组1.concat(数组2);
- 可以连接两个或多个数组并返回新数组
- 不会对原数组产生影响
join()
数组名.join()
- 将原数组转换为字符串返回
- 不会对原数组产生影响
- 可以指定一个字符串作为参数, 这个字符串将成为数组中元素的连接符
reverse()
数组名.reverse();
- 反转数组
- 会直接修改原数组
sort()
数组名.sort()
数组名.sort(function(a, b){ //使数字升序排列 return a - b; });
回调函数需要定义两个形参, 浏览器将分别使用数组中的元素作为实参蛆调用回调函数
使用哪个元素调用不确定, 但在数组中a一定在b前面
浏览器会根据调用函数的返回值决定函数的顺序
若返回大于0的值, 则元素会交换顺序
若返回小于0的位置, 则元素不交换顺序
若返回0, 则认为两个元素相等, 不交换顺序
默认按照Unicode编码进行从小到大排序
会直接修改原数组
对于纯数字数组, 默认也按照Unicode编码排序, 因此对数字排序是, 可能得到错误结果
可以在sort()中添加一个回调函数来指定排序规则
Date
JS中使用Date对象来表示一个时间
是一个函数对象
创建一个Date对象
//封装当前代码执行的时间 var d = new Date();
创建一个指定的时间对象需要在构造函数中传递一个表示时间的字符串作为参数
月份(两位数)/日(两位数)/年(四位数) 时:分:秒
Date方法
getDate()
获取当前日期对象是几日
getDay()
获取当前日期对象是周几(0-6) 0表示周日
getMonth()
获取当前对象的月份数(0-11)
getFullYear()
获取当前对象的四位数年份
getHours()
getMinutes
getSeconds()
getMiliseconds()
getTime()
获取当前日期的时间戳
时间戳
从格林威治标准时间的1970年00:00:00到当前日期对象所经历的毫秒数
计算机底层在保存时间时使用都是时间戳
获取当前的时间戳 time = Date.now()
可以利用时间戳来测试代码的执行性能
Math
不是构造函数, 属于工具类
封装了数学运算相关的属性方法
属性
PI 圆周率
E 自然常量e
方法
abs() 绝对值
ceil() 对一个数进行向上取整
floor() 对一个数进行向下取整
round() 对一个数进行四舍五入取整
random() 生成0-1之间的随机数
max() 获取多个数中的最大值
min() 获取多个数中的最小值
sqrt() 对数字进行开方运算
pow(x, y) 返回x的y次幂
作用域
全局作用域
- 在页面打开时创建, 在页面关闭时销毁
- 全局作用域中有一个全局对象window, 代表一个浏览器的窗口, 由浏览器创建, 可以直接使用
- 在全局作用域中创建的变量都会作为window对象的属性保存
- 在全局作用域中创建的函数都会作为window对象的方法保存
- 全局作用域中的变量都是全局变量, 在页面的任意部分都可以访问
变量的声明提前
- 使用var关键字声明的变量, 会在所有代码执行之前被声明, 在var代码所在的位置进行赋值(赋值之前的值为undefined)
- 如果声明变量时不使用var关键字, 则变量不会被声明提前
函数的声明提前
使用函数声明形式创建的函数function 函数名(){}
会在所有代码执行之前就被创建, 所以可以在函数声明前进行调用
使用函数表达式创建的函数var 函数名 = function(){}
不会被声明提前, 不能在声明前被调用
函数作用域
- 在函数作用域可以访问全局作用域中的变量, 在全局作用域中无法访问函数作用域中的变量
- 在函数作用域中操作一个变量时, 会优先在自身作用域中寻找, 没有则向上一级作用域寻找, 若在全局作用域中仍没有找到, 则报错
- 在函数作用域中要使用全局作用域中的变量可以使用window对象
- 在函数作用域中也有声明提前的特性
- 在函数中, 不用var声明的变量都会成为全局变量
- 定义形参相当于在函数作用域中声明了变量
this
解析器在调用函数每次都会向函数内部传递一个隐含的参数(this)
- this指向一个对象, 称为函数执行的上下文
- 根据函数调用方式的不同, this会指向不同的对象
- 以函数的形式调用时, this永远是window
- 以方法的形式调用时, this就是调用方法的对象
- 当以构造函数的形式调用时, this就是新创建的对象
- 使用call()和apply()调用时, this是指定的对象
包装类
JS中提供了三个包装类, 通过三个包装类可以将基本数据类型转换为对象
String()
Number()
Boolean()
var 变量名 = new String/Number/Boolean(值);
在实际应用中不会使用基本数据类型的对象
如果使用基本数据类型的对象, 在作比较时可能带来不如预期的结果
方法和属性只能添加给对象, 不能添加给基本数据类型
当对基本数据类型调用属性和方法时, 浏览器会临时使用包装类将其转换为对象, 再调用对象的属性和方法, 调用完以后, 再将其转换为基本数据类型
String对象
- 字符串是以字符数组的形式保存的, 适用于所有数组操作
方法
都不会影响到原数组
charAt()
返回字符串中指定位置的字符
传递索引为参数
字符串名.charAt()
charCodeAt()
返回字符串中指定位置字符的Unicode编码
传递索引为参数
字符串名.charCodeAt()
fromCharCode()
是函数的方法
可以根据字符编码获取字符
String.fromCharCode(编码)
concat()
- 可以用来链接两个或多个字符串
- 字符串作为参数传递, 用,隔开
- 相当于+
indexOf()
- 可以检索字符串中是否含有指定内容
- 若字符串中含有该内容, 则返回第一次出现的索引
- 或字符串中不含改内容, 则返回-1
- 可以指定第二个参数, 作为开始查找的位置
lastIndexOf()
- 用法与indexOf()相同
- 从后往前检索
substring()
- 作用和用法和slice()类似
- 无法接收负数参数, 如果传递负数参数, 默认使用0,
- 会自动调整参数的位置, 如果第二个参数小于第一个, 则自动交换
substr()
- 截取开始的索引
- 截取的长度
- 作用同上
- 参数:
split()
- 需要一个字符串作为参数, 将会根据该字符串去拆分数组
- 如果传递一个空串, 则将每个字符都拆分
可以将一个字符串拆分成一个数组
参数:
str = "abc, def, ghi"; result = str.split(",");
toLowerCase()
把字符串转换为小写
toUperCase()
把字符串转换为大写
正则表达式
用于定义一些字符串的规则
计算机可以根据正则表达式来检查一个字符串是否符合规则或将字符串中符合规则的内容提取出来
创建正则表达式
- 使用字面量方式创建更简单
- 使用构造函数创建更灵活
创建正则表达式对象
var 变量 = new RegExp("正则表达式", "匹配模式");
使用字面量创建正则表达式
var 变量 = /正则表达式/匹配模式;
正则表达式语法
被检查字符串中寻找的内容
- |表示或
- []也表示或
- [ab] == a|b
- [a-z]表示任意小写字母
- [A-z]表示任意字母
- [0-9]表示任意数字
- a[bde]c == abc|adc|aec
- [^ab]除了a和b以外的
- 量词
- 只对前面的一个内容起作用
- x{n} x出现且仅出现n次
- x{m,n}x出现m至n次
- x{m,}x出现m次以上
- x+x出现至少一次, 相当于x{1,}
- x*x出现0次或多次, 相当于x{0,}
- x?x出现0次或一次, 相当于x{0,1}
- ^表示开头
- $表示结尾
- .表示任意字符
- \表示转义字符
- \.表示.
- \\表示\
- 使用构造函数时, 由于参数是一个字符串, 而\是字符串中的转义字符, 如果要使用\则需要使用\\来代替
- 一些特殊字符
- \w 任意字母, 数字, _ [A-z0-9_]
- \W 除了字母, 数字, _ [^A-z0-9_]
- \d任意数字[0-9]
- \D除了数字[^0-9]
- \s空格
- \S除了空格
- x\bx是单词的边界
- x\Bx不是单词边界
范例
//检索手机号的正则表达式 /^1[3-9][0-9]{9}$/ //接收用户名并去除前后的空格 var str = prompt("清输入你的用户名"); str = str.replace(/^\s*|\s*$/g, "") //检索邮箱的正则表达式 /^\w{3,}(\.\w+)*@[A-Za-z0-9]+(\.[A-Za-z]{2,5}){1,2}$/
匹配模式
i 忽略大小写
g 全局匹配模式
test()
正则表达式对象.test(字符串)
- 用于检查一个字符串是否符合正则表达式的规则(返回true或false)
- 严格区分大小写
字符串和正则表达式相关的方法
split()
可以传递一个正则表达式作为参数
方法将会根据正则表达式拆分字符串
不用指定全局匹配也会全部拆分
字符串名.split(/正则表达式/)
search()
可以搜索字符串中是否含有指定内容
如果搜索到指定内容, 则返回第一次出现的索引
如果未搜索到指定内容, 则返回-1
可以接收一个正则表达式作为参数, 然后根据正则表达式检索字符串
即使设置全局匹配, 也只返回第一次出现的索引
字符串名.search(/正则表达式/)
match()
可以根据正则表达式, 从一个字符串中将符合条件的内容提取出来
字符串名.match(/正则表达式/);
默认情况下只会找到第一个符合要求的内容, 找到以后则停止检索
可以设置正则表达式为全局匹配模式
可以为一个正则表达式设置多个匹配模式, 且顺序无所谓
字符串名.match(/正则表达式/ig);
会将匹配到的对象封装到数组中返回
replace()
可以将字符串中的指定内容替换为新的内容
参数:
默认只替换第一个
被替换的内容, 可以接受一个正则表达式作为参数
新的内容, 传递空串""相当于删除对应内容
DOM
简介
全称 Document Object Model
文档(document)
表示整个HTML网页文档
对象(object)
表示将网页中的每一个部分都转换为了一个对象
模型(model)
使用模型表示对象之间的方式, 方便获取对象
节点(Node)
- 构成网页的基本组成部分, 网页的每个部分都是节点
- 常用节点
- 文档节点: 整个HTML文档
- 元素节点: HTML文档中的HTML标签
- 属性节点: 元素的属性
- 文本节点: HTML标签中的文本内
节点的属性
DOM查询
通过document对象调用
通过id属性获取一个元素节点
通过标签名获取一组元素节点(以数组形式)
通过name属性获取一组元素节点
通过class属性获取一组元素节点
不支持IE8及以下的浏览器
- getElementsByClassName()
- getElementsByName()
- getElementsByTagName()
- getElementById()
通过具体的元素节点调用子节点
方法, 返回当前节点的指定标签名后代节点
属性, 表示当前节点的所有子节点
会获取包括文本节点在内的所有子节点
根据DOM标签 标签间空白也会被当成文本节点(换行等)
在IE8及以下的浏览器中, 不会将空白文本当成子节点
属性, 表示当前节点的第一个子节点(包括空白文本节点)
属性, 表示当前节点的最后一个子节点
可以获取当前元素的所有子元素
可以获取当前元素的第一个子元素
不支持IE8及以下的浏览器
可以获取当前元素的最后一个子元素
不支持IE8及以下的浏览器
- lastElementChild
- firstElementChild
- children
- lastChild
- firstChild
- childNodes
- getELementByTagName()
通过具体的元素节点调用父节点和兄弟节点
属性, 表示当前节点的父节点
属性, 表示当前节点的前一个兄弟节点
属性, 表示当前节点的后一个兄弟节点
- nextSibling
- preciousSibling
- parentNode
其他方法
相当于document.getElementByTagName("*")
需要一个选择器的字符串作为参数, 可以根据一个CSS选择器来查询一个元素节点对象
使用该方法只会返回第一个元素
和querySelector方法类似, 但会将所有符合条件的元素封装进数组中
- document.querySelectorAll()
- document.querySelector()
document.body保存了对body的引用
document.documentElement保存的是html根标签
document.all代表页面中的所有元素
DOM增删改
document.createELement()
可用于创建一个元素节点对象
需要一个标签名作为参数, 将会根据该标签名创建元素节点对象, 并将创建好的对象返回
document.createTextNode()
可用于创建一个文本节点对象
需要一个文本内容作为参数, 将会根据该内容创建文本节点, 并将新的节点返回
父元素.appendChild(子节点)
向一个父元素中添加一个子节点
父节点.insertBefore(新的子节点, 原有子节点)
在指定子节点前面添加新的子节点
父节点.removeChild(子节点)
删除一个子节点
子节点.parentNode.removeChild(子节点)
父节点.replaceChild(新节点, 旧节点)
可使用指定的节点替换已有节点
节点.innerHTML
用于获取(修改)对应节点内的内容
节点.innerHTML = 修改后的新内容
节点.innerHTML += 需要添加的新内容
一般和增的操作结合使用
用DOM操作CSS
修改元素样式
元素.style.样式名 = 样式值
如果css的样式名中含有-, 这种名称在JS中是不合法的例如background-color
需要将-去掉, 大写后面部分的首字母
box1.style.backgroundColor = "FFF"
通过style属性设置的样式都是内联样式, 有较高的优先级, 所以通过JS修改的样式往往会立即显示
但如果样式中写了 !important, 则此时样式有最高的优先级,
即使通过JS也无法覆盖该样式, 导致JS修改样式失效, 因此尽量不要为样式添加!important
通过元素.style.样式名读取的都是内联样式, 无法读取样式表中的样式
读取元素样式
元素.currentStyle.样式名
用于读取元素当前显示的样式
如果当前元素没用设置该样式, 则获取默认值(如 width获取auto)
只有IE浏览器支持, 其他浏览器都不支持
getComputedStyle();
需要两个参数:
该方法会返回一个对象, 对象中封装了当前元素对应的样式
如果获取的样式没用设置, 则会获取到真实的值, 而不是默认值(如width获取当前宽度)
不支持IE8以下的浏览器
要获取样式的元素
2. 可以传递一个伪元素, 一般传null
通过以上两种方式读取到的样式都是只读的, 不能修改, 如果要修改, 必须通过style属性
function getStyle(obj, name){ if(getComputedStyle){ return getComputedStyle(obj, null)[name]; }else{ return obj.currentStyle.[name]; } //return window.getComputedStyle?getComputedStyle(obj, null)[name]:obj.currentStyle.[name]; }
其他操作
clientWidth clientHeight
可以获取元素的可见宽度和高度, 包括内容区和内边距
返回值是一个数字(不带px), 可以直接进行计算
只读, 不能修改
offsetWidth offsetHeight
获取元素的整个宽度和高度, 包括内容区, 内边距, 边框
offsetParent
可以获取当前元素的定位父元素
会获取到离当前元素最近的开启了定位的祖先元素
如果所有祖先元素都没开启定位, 则返回body
offsetLeft offsetTop
当前元素相对其父元素的水平偏移量和垂直偏移量
scrollWidth scrollHeight
可以获取元素整个滚动区域的宽度和高度
scrollLeft scrollTop
可以获取元素水平和垂直滚动的距离
当满足scrollHeight - scrollTop = clientHeight时, 说明滚动条滚到底了
事件对象
简介
当事件的响应函数被触发时, 浏览器每次都会将一个事件对象作为实参传递进响应函数
在事件对象中封装了当前事件相关的一切信息, 比如: 鼠标的坐标clientX, clientY
在IE8及以下的浏览器中, 响应函数被触发时, 浏览器不会传递事件对象
是将事件对象作为window对象的属性保存的(如: window.event.clientX)
常用事件
鼠标事件
onmousemove
将会在鼠标在元素中移动时被触发
onmousedown onmouseup
鼠标在元素中按下/释放时触发
setCapture() releaseCapture()
当调用一个元素的setCapture()方法以后, 这个元素会把下一次所有鼠标按下相关的事件捕获到自身上
只有IE有setCapture()releaseCapture()和方法
box1.setCapture && box1.setCapture(); box1.releaseCapture && box1.releaseCapture();
onmousewheel
在鼠标滚轮在元素中滚动时被触发
火狐不支持该属性
火狐中需要使用DOMMouseScroll来绑定滚动事件
该事件需要通过addEventListener()函数来绑定
键盘事件
onkeydown onkeyup
按键被按下/松开
一般被绑定给一些可以获取到焦点的对象或者documen
对于onkeydown, 若一直按住一个按键不松手, 则事件会被连续触发
onkeydown连续触发时, 第一次和第二次之间的间隔较长, 之后会非常快, 用于防止误操作
在文本框中输入内容, 属于onkeydown的默认行为, 可以通过return false取消
//使文本框无法输入数字 if(event.keyCode >= 48 && event.keyCode <= 57) return false;
事件对象的属性
clientX clientY
获取鼠标在当前可见窗口的坐标
div的偏移量是相对于整个页面
pageX pageY
获取鼠标相对当前页面的坐标
在IE8以下的浏览器不支持
chrome认为浏览器的滚动条是body的, 可以通过body.scrollTop来获取
火狐浏览器认为浏览器的滚动条是HTML的, 可以通过documentElement.scrollTop来获取
var left = event.clientX; var top = event.clientY; var st = document.body.scrollTop||document.documentElement.scroll; var sl = document.body.scrollLeft||document.documentElement.scrollLeft; box1.style.top = top + st + "px"; box1.style.left = top + sl + "px";
target
触发事件的元素
wheelDelta
可以获取鼠标滚轮滚动的方向
向上滚是正值, 向下滚是负值
火狐中不支持, 在火狐中使用event.detail来获取滚动方向
大小与方向的关系和wheelDelta正好相反
if(event.wheelDelta > 0 | event.detail < 0) alert("向上滚动"); else alert("向下滚动");
keyCode
返回按键的编码, 通过它可以判断哪个按键被按下
altKey ctrlKey shiftKey
用来判断alt ctrl shift是否被按下 返回值为true/false
事件的冒泡
指事件的向上传导, 当后代元素上的事件被触发时, 其祖先元素的相同事件也会被触发
如果不希望发生事件, 可以通过事件对象取消冒泡event.cancelBubble = true
事件的委派
指将事件统一绑定给元素的共同的祖先元素, 这样当后代元素上的事件被触发时, 会一直冒泡到祖先元素, 从而通过祖先元素的响应函数来处理事件
事件委派是利用了冒泡, 通过委派可以减少事件的绑定次数, 提高程序的性能
//如果触发事件的元素是我们期望的元素, 则执行 if(event.target.className == ""){ //执行的内容 }
事件的绑定
使用对象.事件 = 函数的形式绑定响应函数, 只能同时为一个元素的一个事件绑定一个响应函数, 无法绑定多个, 否则后面的会覆盖前面的
addEventListener()
可以同时为一个元素的相同事件同时绑定多个响应函数, 当事件被触发时, 响应函数会按照函数的绑定顺序执行
参数:
btn.addEventListener("click", function(){ //内容 }, false);
- 事件的字符串, 不要on
- 回调函数, 当事件触发时, 当函数会被调用
- 是否在捕获阶段触发事件, 需要一个布尔值, 一般传false
this是绑定事件的对象
使用addEventListener()绑定的响应函数, 取消默认行为时不能使用return false, 需要使用event来取消默认行为 IE8以下不支持该方法
event.preventDefault && event.preventDefault();
不支持IE8以下的浏览器
attachEvent()
仅支持在IE8及以下中使用
参数:
btn.attachEvent("onclick", function(){ //内容 });
- 事件的字符串, 要on
- 回调函数
可以为同一个事件绑定多个处理函数, 后绑定的先执行
this是window
完成bind函数
//参数: // 1. obj 要绑定事件的对象 // 2. eventStr 事件的字符串 // 3. callback 回调函数 function bind(obj, eventStr, callback){ if(obj.addEventListener){ //大部分浏览器兼容的方式 obj.addEventListener(eventStr, callback, false); }else{ //IE8及以下 obj.attachEvent("on" + eventStr, function(){ //在匿名函数中调用回调函数 callback.call(obj); }); } }
事件的传播
关于事件的传播网景公司和微软公司有不同的理解
微软公司认为事件应该由内向外传播, 也就是说事件应该在冒泡阶段执行
网景公司认为事件应该是由外向内传播的
W3C综合了两个公司的方案, 将事件传播分成了三个阶段
捕获阶段
在捕获阶段时从最外层的祖先元素向目标元素进行事件的捕获, 但默认此时捕获触发事件
目标阶段
事件捕获到目标元素
冒泡阶段
事件从目标元素向祖先元素传递, 依次触发祖先元素的事件
如果希望在捕获阶段就触发事件, 可以将addEventListener()的第三个参数设置为true 一般情况下不用
IE8以下的事件没有捕获阶段
BOM
- 浏览器模型
- 可以通过js操作浏览器
- 在BOM中提供了一组对象, 用于提供浏览器操作
- BOM对象是作为Window对象的属性保存的, 可以通过window对象来使用, 也可以直接使用
Window
代表整个浏览器的窗口, 同时window也是网页中的全局变量
setInterval()
按照指定的周期(以毫秒记)来调用函数或计算表达式
参数:
返回值:
返回一个Number类型的数据, 用来作为定时器的唯一标识
- 每次调用间隔的时间
回调函数, 每隔一段时间被调用一次
setTimeout()
在指定的毫秒数后调用函数或计算表达式, 只执行一次
和定时调用可以互相代替
clearInterval() clearTimeout()
取消由setInterval()/setTimeout()设置的timeout
需要定时器的标识作为参数
可以接收任意函数作为参数, 包括none undefined
若参数是一个有效的定时器标识则关闭标识对应的定时器, 否则什么都不做
Navigator
代表当前浏览器的信息, 通过该对象可以识别不同浏览器的信息
由于历史原因, Navigator对象中的大部分属性已经无法帮助我们识别不同浏览器了
一般只会使用userAgent来判断浏览器信息
userAgent
一个字符串, 包含用来描述浏览器信息的内容
不同的浏览器有不同的userAgent
if(/Firefox/i.test(navigator.userAgent)) alert("火狐浏览器"); else if(/Chrome/i.test(navigator.userAgent)) alert("谷歌浏览器"); else if(/msie/i.test(navigator.userAgent)) //在IE11中已经将微软和IE相关的消息去除了, 所以无法通过userAgent来识别一个浏览器是否IE alert("IE8-10浏览器") else if("ActiveXObject" in window) alert("IE11, 我杀了你") //如果通过UserAgent不能判断, 还可以通过一些浏览器中特有的对象来判断浏览器的信息 //if(window.ActiveXObject) // alert("IE10及以下浏览器"); //else // alert("IE11有病吧");
Location
代表当前浏览器的地址栏信息, 通过location可以获取地址栏信息, 或操作浏览器跳转页面
如果直接将Location属性修改为一个完整的路径或相对路径, 则页面会自动跳转到改路径, 并生成相应的历史记录
assign()
用于跳转到新的页面, 作用和直接修改location相同
reload()
重新加载当前页面, 作用和刷新按钮相同
如果在方法中传递true作为参数, 则会强制清空缓存刷新
replace()
可以使用新的页面替换当前页面, 调用完毕也能跳转页面, 但不会生成历史记录, 无法回退
History
代表浏览器的历史记录, 可以通过该对象来操作浏览器的历史记录
由于隐私原因, 该对象不能不能获取具体的历史记录, 只能操作浏览器向前或向后
且该操作只对当此访问时有效
length
可获取当次访问的链接数量
back()
可以用来回退到上一个界面
forward()
可以跳转下一个界面
go()
可以用来跳转到指定的页面
需要一个整数作为参数
正数为向前跳转页数, 负数为向后跳转页数
Screen
代表用户的屏幕信息, 通过该对象可以获取到用户的显示器的相关信息
JSON
- JavaScript Object Notation JS对象表示法
- JS中的对象只有JS能够读懂, 其他语言都无法读懂
- JSON就是一个特殊格式的字符串, 这个字符串可以被任意的语言所识别, 并且可以转换为任意语言中的对象, JSON在开发中主要用来数据的交互
- JSON和JS对象的格式一样, 不过JSON字符串中的属性名必须加双引号
- JSON这个对象在IE7及以下的浏览器中不支持
JSON的使用
JSON分类
1. 对象{} 2. 数组[]
JSON中允许的值
1. 字符串 2. 数值 3. 布尔值 4. null 5. 对象 6. 数组
JSON方法
在JS中, 提供了一个工具类JSON, 可以帮助我们将一个JSON对象和JS对象互相转换
JSON.parse()
可以将JSON字符串转换为js对象
需要一个JSON字符串作为参数, 会将该字符串转换为JS对象并返回
JSON.stringify()
可以将JS对象转换为JSON
需要一个JS对象作为参数, 会返回一个JSON字符串
IE7及以下浏览器中
eval()
可以用来执行一串字符串形式的代码, 并将执行结果返回
//如果使用eval()执行的字符串中含有{}, 会将{}当成代码块 //如果不希望将其当成代码块解析, 则需要在字符串前后加() var str = '{"name": "Ann", "age": 20, "gender": "female"}'; obj = eval("(" + str + ")");
eval()函数的功能很强大, 可以直接执行一个字符串中的代码, 不建议在开发中使用:
- 执行性能较差
- 具有安全隐患
常用函数
获取当前元素样式
//参数: // 1. ibj 要获取样式的元素 // 2. 获取样式的名字 function getStyle(obj, name){ if(getComputedStyle){ return getComputedStyle(obj, null)[name]; }else{ return obj.currentStyle[name]; } //return window.getComputedStyle?getComputedStyle(obj, null)[name]:obj.currentStyle.[name]; } //parseInt(getStyle(obj, left)) 返回偏移量的数字值
为指定元素绑定事件
//参数: // 1. obj 要绑定事件的对象 // 2. eventStr 事件的字符串 // 3. callback 回调函数 function bind(obj, eventStr, callback){ if(obj.addEventListener){ //大部分浏览器兼容的方式 obj.addEventListener(eventStr, callback, false); }else{ //IE8及以下 obj.attachEvent("on" + eventStr, function(){ //在匿名函数中调用回调函数 callback.call(obj); }); } }
简单动画效果
//尝试创建一个可以执行简单动画的函数 /* * 参数: * obj:要执行动画的对象 * attr:要执行动画的样式,比如:left top width height * target:执行动画的目标位置 * speed:移动的速度(正数向右移动,负数向左移动) * callback:回调函数,这个函数将会在动画执行完毕以后执行 */ function move(obj, attr, target, speed, callback) { //关闭上一个定时器 clearInterval(obj.timer); //获取元素目前的位置 var current = parseInt(getStyle(obj, attr)); //判断速度的正负值 //如果从0 向 800移动,则speed为正 //如果从800向0移动,则speed为负 if(current > target) { //此时速度应为负值 speed = -speed; } //开启一个定时器,用来执行动画效果 //向执行动画的对象中添加一个timer属性,用来保存它自己的定时器的标识 obj.timer = setInterval(function() { //获取box1的原来的left值 var oldValue = parseInt(getStyle(obj, attr)); //在旧值的基础上增加 var newValue = oldValue + speed; //判断newValue是否大于800 //从800 向 0移动 //向左移动时,需要判断newValue是否小于target //向右移动时,需要判断newValue是否大于target if((speed < 0 && newValue < target) || (speed > 0 && newValue > target)) { newValue = target; } //将新值设置给box1 obj.style[attr] = newValue + "px"; //当元素移动到0px时,使其停止执行动画 if(newValue == target) { //达到目标,关闭定时器 clearInterval(obj.timer); //动画执行完毕,调用回调函数 callback && callback(); } }, 30); }
对类的操作
//判断是否含有class function hasClass(obj, cn){ var reg = new RegExp("\\b" + cn + "\\b"); return reg.test(obj.className); } //添加class function addClass(obj, cn){ if(!hasClass(obj, cn)) obj.className += " " + cn; } //删除元素中的指定class function remove(obj, cn){ var reg = new RegExp("\\b" + cn + "\\b"); obj.className = obj.className.replace(reg, ""); } //如果元素中有对应类, 则删除, 如果没有则添加 function toggleClass(obj, cn){ if(hasClass(obj, cn)){ removeClass(obj, cn); }else{ addClass(obj, cn); } }
注: 是看着尚硅谷JavaScript基础全套教程完整版学习的, 仅供复习用