目录
目录
JavaScript
一、初步认识JavaScript
二、JavaScript基础
1、JS编写位置
2、JS基本语法
3、基本数据类型
4、引用数据类型(Object)
5、数据类型的强制转换
6、运算符
7、代码块
8、流程控制语句
9、变量与对象保存位置
10、对象的遍历
10.对象补充
11、函数(Function)
11.2.call()、apply()方法
11.3.作用域
11.4.this(上下文对象)
11.5.构造函数
11.6.原型(prototype)
11.7.toString方法
11.8.垃圾回收(GC)
12、数组(Array)
1、数组特点
2、数组的操作
3、二维数组
4、数组的方法
slice()
splice()
join()
filter()
sort()
5、遍历数组
13、常用类和方法
13.1.包装类
13.2.Date
13.3.Math
13.4.字符串的相关的方法
13.5.正则表达式
13.6.正则表达相关方法
13.7常用正则表达式
14、DOM(Document Object Model)
14.1.DOM介绍
14.2.DOM查询
14.3.DOM其它属性和方法
14.4.DOM修改(增、删、改)
14.5.DOM对CSS的操作
读取和修改内联样式
读取元素的当前样式
其他的样式相关的属性
事件(Event)
事件
绑定事件的方式
文档的加载
事件对象(event)
事件的冒泡(Bubble)
事件的委派
事件的绑定
事件的传播
常用事件
鼠标事件
键盘事件
BOM
History
Location
window
定时器
setTimeout 延时调用
直接修改元素的类css
JSON
JSON 格式
JSON工具类
other
localStorage
sessionStorage
eval()
编码
原生js
原生js实现复制内容到剪切板
起源
JavaScript诞生于1995年,它的出现主要是用于处理网页中的前端验证。
所谓的前端验证,就是指用户输入的内容是否符合一定的规则。
比如:用户名的长度,密码的长度,邮箱的格式等。
实现
一个完整的JavaScript实现由以下三个部分构成:
ECMAScript
DOM
BOM
控制浏览器弹出一个警告框 alert()
用于弹出一个带有确认和取消按钮的提示框 confirm()
需要一个字符串作为参数,该字符串将作为提示文字显示出来
如果用户点击确认则会返回true,点击取消则返回false(可以对一个事件是否执行,进行判断)
弹出一个提示框 prompt()
让计算机在页面(body)中输出一个内容 document.write()
向控制台输出一个内容 console.log()
1.1、JS代码写到script标签中
1.2、JS代码写到外部js文件中
通过script标签引入写到外部文件中可以在不同的页面中同时使用
注意:script标签一旦用于引入外部文件,就不能再编写代码,即使编写浏览器也会忽略
1.3、JS代码写到标签属性中
缺点是结构与行为耦合,不方便维护,不推荐使用
点我一下
你也点我一下
JS中严格区分大小写
JS中每一条语句以分号(;)结尾
若不写分号,浏览器会自动添加,但是会消耗一些系统资源,而且有些时候,浏览器会加错分号,所以在开发中分号必须写
JS中会忽略空格和换行
字面量与变量
字面量:不可改变的值。如:1、 2、 1.0 、True
变量:保存字面量,变量的值可以任意改变,可以对字面量进行描述
声明变量
在js中使用var关键字来声明一个变量
标识符
与C中基本类似,除此以外,在js命名一个标识符可以含有$。
命名一个标识符时需要遵守如下规则:
a、标识符中可以含有字母、数字、_、$
b、标识符不能以数字开头
c、标识符不能是ES中的关键字或保留字
d、标识符一般都采用驼峰命名法
首字母小写,除首字母外的每个单词的开头字母大写。如:helloWorld
3.1、Number
整数、浮点数、NaN
NaN:Not a Number
NaN(Not a Number,非数)是计算机科学中数值数据类型的一类值,表示未定义或不可表示的值。常在浮点数运算中 使用。首次引入NaN的是1985年的IEEE 754浮点数标准。
JS中可以表示的数字的最大值(1.7976931348623157e+308)
JS中可以表示的大于0的最小值(5e-324)
检查数据类型 typeof
Infinity
3.2、string
没什么好说的,就那样
3.3、boolean
主要用来逻辑判断
True:真 False:假
3.4、Null
Null这个值专门用来表示一个为空的对象
3.5、undefined(未定义)
当声明一个变量,但是并不给变量赋值时,它的值就是undefined。
3.7、Symbol,BigInt
Symbol
JavaScript标准中规定对象的key只能是 String
或 Symbol
类型,区别在于 String
类型的key可以重复而 Symbol
类型的key是唯一的。Symbol
的本质是表示一个唯一标识。每次创建一个Symbol,它所代表的值都不可能重复。
const sym = Symbol('cat');
Symbol特点
1、唯一性,即使是同一个变量生成的值也不相同
2、隐藏性,不能被遍历,访问
调用 Object.getOwnPropertySymbols(对象),可以访问到所有Symbol
BigInt用来表示任意大的整数
Number < 2的53 -1
BigInt表示方法
1、在整数后加n
123n
2、调用BigInt()构造函数
let bigInt = BigInt("999");
console.log(bigInt) //999n
注意:调用BigInt()构造函数,会对参数进行转换
true --- 1 BigInt(true) --- 1n
false --- 0 BigInt(true) --- 0n
'整数' --- 整数 BigInt('123') --- 123n
无法转换的数据类型
RangeError:浮点数
TypeError:null,undefined
SyntaxError:非整数的字符串,一般对象,函数对象,元素个数大于1的数组
3.8、基本类型存放位置
NAME | |
---|---|
字符串 存在堆中,栈中为引用地址;如果存在相同字符串,则引用地址相同 | |
String对象存在堆中, | |
数字 小整数存在栈中,其它存在堆中 | |
其它类型 引擎初始化时分配唯一地址,栈中的变量存的是唯一的引用 |
栈和堆的区别:JavaScript 中堆和栈的区别you_wne的博客-CSDN博客js堆和栈的区别
变量存储机制:JavaScript中变量到底是存储在「栈」还是「堆」上? - 知乎 (zhihu.com)
object(使用基本数据类型的数据,所创建的对象都是独立的,不能够成一个整体。
对象可以保存多个不同数据类型的属性)
对象的分类:
内建对象
-由ES标准中定义的对象,在任何ES的实现中都可以使用
-比如:Math String Number Object……
宿主对象
-由JS的运行环境提供的对象,主要指由浏览器提供的对象
-比如:BOM DOM(console.log())
自定义对象
-由开发人员自己创建的对象
创建对象的方式:
1、使用new关键字调用的函数,是构造函数constructor
构造函数是专门用来创建对象的函数
使用typeof检查一个对象时,会返回object
var obj = new Object();
向对象中添加属性:
$$
语法:对象.属性名 = "属性值";
$$
obj.name="孙悟空";
注意:如果读取对象中没有的属性,不会报错而是会返回undifined
2、
使用对象字面量来创建一个对象 语法: ①var obj = {}; ②var obj = { 属性名 :"属性值", 属性名 :"属性值", 属性名 :"属性值", 属性名 :"属性值" } 属性名和属性值是一组一组的名值对结构 名和值之间使用':'连接,多个名值对之间使用','隔开 若一个属性之后没有其他的属性,则不需要加','
注意:对象字面量的属性名引号可加可不加,建议不加
对象的属性名类型都是字符串,符合命名规则的属性,可以不加引号
如果使用特殊字符、名字(非合法命名规则),则属性名必须加引号
特殊字符、名字的读取:obj["属性名"] = 属性值
var obj3 = {888name :"hello" };
var obj4 = { :"hello" };
//报错
此时会报错
修改对象的属性值:
$$
语法:对象.属性名=新值
$$
删除对象的属性:
$$
语法:delete 对象.属性名
$$
注意:如果使用特殊的属性名,不能采用 . 的方式来操作
而是:语法:对象["属性名"]=属性值
in 运算符:
作用:检查一个对象中是否含有指定的属性
如果有则返回true,没有则返回false
语法: "属性名" in 对象
对象的比较:
当比较两个基本数据类型的值时,就是比较值
当比较两个引用数据类型时,它是比较的对象的内存地址
5.1、其他的数据类型转换为String
方式一:调用toString()
方法:x.toString()
注意:null和undefined不能调用toString()
方式二:调用String()
5.2、其他的数据类型转换为Number
使用Number()函数
string-->number
如果是纯数字字符串,则直接将其转换为数字
如果字符串中有非数字的内容,则转换为NaN
如果字符串是一个空串或者是一个全是空格的字符串,则转换为0
Boolean-->number
true------1, false------0
Null-->0
undefined-->NaN
2、调用parseInt()、parseFloat()函数
parseInt()、parseFloat()函数可以分别将一个字符串中的有效整数、有效浮点数解析出来,然后转换为number
允许前导和尾随空格。
parseInt(" 123 "); //123
如果第一个字符不能转换为数字,
parseInt()
返回 NaN。parseInt("") // NaN
指定字符串中的第一个字符是否为数字。如果是,它会解析字符串直到到达数字的末尾,并将数字作为数字而不是字符串返回。只会对解析到的第一个小数点生效。
parseInt(" 123as12"); //123
parseFloat(".123as1"); //0.123
parseFloat(".123.as"); //0.123
可以在parseInt()中传递第二个参数,来指定数字的进制
5.3、其他的数据类型转换为Boolean
1、使用Boolean()函数
数字-->布尔
除了0和NaN,其余的都是true
字符串-->布尔
除了空串,其余的都是true
null和undefined都会转换为false
对象也会转换为true
2、对该数据类型进行两次取反操作
5.4、隐式转换
任何值和字符串相加都会转换为字符串,并做拼串操作
任何值做' - * / ' 运算时,都会自动转换为Number
在其它数据类型前使用'正号+',会将其转换为Number
6.1、算术运算符
当对非number类型的值进行运算时,会将这些值转换为Number(若不能转换为number,则运算会报错),然后在运算
任何值和NaN做运算都得NaN
+
对两个值进行加法运算
对两个字符串进行拼串
-
*
\
%
6.2、一元运算符
只需要一个操作数
+ 正号(不会对数字产生任何影响)
- 负号(对数字进行取反)
6.3、逻辑运算符
! :对布尔值进行取反操作
若对非布尔值进行非运算,则会先转换为布尔值,然后再取反
&&:具有短路性
||:具有短路性
&&和||非布尔值的情况:
对非布尔值进行与或运算时,会先将其转换为布尔值,然后再运算,并且返回原值
6.4、关系运算符
通过关系运算符可以比较两个值之间的大小关系,如果关系成立则会返回true,反之返回false
任何值和NaN做任何比较,返回的都是false
对于非数值进行比较时,会将其转换为数字然后再比较
两边都是字符串时,比较的是字符串的字符编码,比较字符编码是一位一位进行比较,若两位一样,则比较下一位
在字符串中使用转义字符输入Unicode编码(\u四位编码)
6.5、相等运算符
==
相等运算符,比较两个值是否相等,相等返回true,否则返回false
当两边值的类型不同时,则会自动转换为相同的类型
!=
===
值相等,类型一致,否则返回false
!==
两边的值的类型不同,直接返回true
注意:undefined衍生自null,所以两个值做相等判断时,会返回true
NaN不和任何值相等,包括它本身,可以通过isNaN()函数来判断一个值是否是NaN,若是则true,否则false
isNaN() :isNaN函数,会先将测试子,进行Number转换,然后对其进行测试
Number.isNaN() :不会将值转换为数字,并且不会为任何非数字类型(NaN)的值返回 true。
6.6、条件运算符
条件运算符又叫三元运算符
语法:
条件表达式?语句1:语句2;
6.7、运算符的优先级
. [ ] NEW | ||||
() | ||||
++、-- | ||||
!、~、+(单目)、-(单目)、typeof、void、delete | ||||
%、*、/ | ||||
+(双目)、-(双目) | ||||
<<、>>、>>> | ||||
<、<=、>、>= | ||||
==、!=、=== | ||||
& | ||||
^ | ||||
| | ||||
&& | ||||
|| | ||||
?: | ||||
=、+=、-=、/=、%=、<<=、>>=、>>>=、&=、^=、|= | ||||
, |
在JS中可以使用{}来为语句进行分组,同一个{}中的语句称为一组语句,它们要么都执行,要么都不执行
在代码块{}的后边不需要加";"
代码块只具有分组的作用,没有其它的用途。代码块中的内容,在外部是完全可见的
if、switch、while、for(--for(;;)<==>while(1)程序进入死循环--)
prompt()可以弹出一个提示框,该提示框中会带有一个文本框
用户可以在文本框中输入一段内容,该函数需要一个字符串作为参数,作为提示框的提示文字
输入的内容将会作为函数的返回值,可以定义一个变量来接收该内容
prompt()函数的返回值是String类型的,
+prompt()-->number类型
var score=prompt("请输入小明的期末成绩:");
栈内存
变量 | 值 |
---|---|
x | 111 |
object | 0x9876 |
保存在栈内存中: JS中的变量、基本数据类型的值 值与值之间是独立存在,修改一个变量不会影响其它的变量 保存在堆内存中: 对象、函数、数组 每创建一个新的对象,就会在堆内存中开辟出一个新的空间, 变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象的引用,当一个通过变量修改属性时,另一个也会受影响
使用in检查对象中是否含有指定属性
语法:"属性名" in 对象
如果在对象中含有该属性,则返回true 如果没有则返回false
循环遍历对象自身的和继承的可枚举属性(不含Symbol属性).
枚举对象中的属性 for...in 语法:
for(var 属性名 in 对象){ }
for...in语句的循环体会执行多次,对象中有几个属性就会执行几次, 每次讲一个属性名赋值给我们定义的变量,我们可以通过它来获取对象中的属性
使用对象字面量,在创建对象时直接向对象中添加属性 语法:
var obj = {
属性名:属性值,
属性名:属性值,
属性名:属性值,
属性名:属性值
}
基本数据类型和引用数据类型
基本数据类型 | ||||
---|---|---|---|---|
String | Number | Boolean | Null | Undefined |
引用数据类型 Object
基本数据类型的数据,变量是直接保存的它的值。 |
---|
变量与变量之间是互相独立的,修改一个变量不会影响其他的变量。 |
引用数据类型的数据,变量是保存的对象的引用(内存地址)。 |
如果多个变量指向的是同一个对象,此时修改一个变量的属性,会影响其他的变量。 |
比较两个变量时,对于基本数据类型,比较的就是值, |
对于引用数据类型比较的是地址,地址相同才相同 |
函数也是一个对象
函数中可以封装一些代码,在需要的时候可以去调用函数来执行这些代码
使用typeof检查一个函数时会返回function
创建函数
创建一个函数对象: var fun = new Function(); 注意:封装到函数中的代码不会立即执行,到调用的时候才会执行 //创建函数对象
var fun = new Function("console.log('hello javascript!')"); fun();
函数声明
function 函数名([形参1,形参2...形参N]){ 语句... }
函数表达式
var 函数名 = function([形参1,形参2...形参N]){ 语句... };
调用函数
语法:函数对象([实参1,实参2...实参N]); 如:fun() sum() alert() Number() parseInt() ********************************************************************************** function sayName(){ ***** }; sayName();-->调用函数 *相当于使用的函数的返回值 sayName;-->函数对象 *相当于使用的函数对象
当我们调用函数时,函数中封装的代码会按照编写的顺序执行 |
---|
调用函数时,解析器不会检查实参的数量、类型,所以要注意是否有可能接收到非法的参数,如果有可能则需要对参数进行类型的检查 |
函数的实参可以是任意数据类型(sum(123,"hello");) |
立即执行函数
函数定义完,立即被调用,这种函数叫做立即执行函数
立即执行函数往往只会执行一次
(function(a,b){
console.log("a = "+a);
console.log("b = "+b);
})(123,456);
((a,b)=>{
console.log("a = "+a);
console.log("b = "+b);
})(123,456);
语法: ((形参1,形参2...形参n)=>{ ********* })(实参1,实参2..实参n);
遍历对象
for(var v in obj){
document.write("property:name ="+v+"value="+obj[v]+"
" );
}
形参和实参 |
---|
形参:形式参数 |
定义函数时 ,可以在()中定义一个或多个形参,形参之间使用,隔开 |
定义形参就相当于在函数内声明了对应的变量但是并不赋值, |
形参会在调用时才赋值。 |
实参:实际参数 |
---|
调用函数时 ,可以在()传递实参,传递的实参会赋值给对应的形参, |
调用函数时JS解析器不会检查实参的类型和个数,可以传递任意数据类型的值。 |
如果实参的数量大于形参,多余实参将不会赋值, |
如果实参的数量小于形参,则没有对应实参的形参将会赋值undefined |
返回值(RETURN),就是函数执行的结果 |
---|
语法:return 值 |
可以通过一个变量来接收返回值 |
return后边的代码都不会执行,一旦执行到return语句时,**函数将会立刻退出 |
return后可以跟任意类型的值,可以是基本数据类型,也可以是一个对象 |
如果return后不跟值,或者是不写return则函数默认返回undefined |
js中Return的用法 (cncsto.com) |
JAVASCRIPT在事件中调用函数时用return返回值实际上是对window.event.returnvalue进行设置
而该值决定了当前操作是否继续。
当返回的是true时,将继续操作。
当返回是false时,将中断操作。
break、continue和return: break 退出循环 continue 跳过当次循环 return 退出函数,不会执行代码块中return 以后的语句 return false,事件处理函数会取消事件,不再继续向下执行(阻止执行的默认行为)。比如表单将终止提交 return True, 就相当于执行符,执行终止默认的事件行为
参数,函数的实参也可以是任意的数据类型。 **方法(method)** 可以将一个函数设置为一个对象的属性, 当一个对象的属性是一个函数时,我们称这个函数是该对象的方法。 **调用这个函数就说调用这个对象的方法(method)** 调用方式:对象.方法名(); 函数名()
CALL()与APPLY() |
---|
1、作用:改变this的指向 |
这两个方法都是函数对象的方法需要通过函数对象来调用 |
通过两个方法可以直接调用函数,并且可以通过第一个实参来指定函数中this |
不同的是call是直接传递函数的实参而apply需要将实参封装到一个数组中传递 |
var person = {
fullName: function(city, country) {
return this.firstName + " " + this.lastName + "," + city + "," + country;
}
}
var person1 = {
firstName:"Bill",
lastName: "Gates"
}
console(person.fullName.call(person1, "Seattle", "USA"));
console(person.fullName.apply(person1, ["Seattle", "USA"]));
//若不将实参封装到数组中会显示:
//Uncaught TypeError: CreateListFromArrayLike called on non-object
arguments
在调用函数时,浏览器每次都会传递进两个隐含的参数: |
---|
1,this 2,封装实参的对象arguments |
arguments是一个类数组对象,它可以通过索引来操作数据 |
在调用函数时,所传递的实参都会在arguments中保存 |
arguments.length可以用来获取实参的长度 |
即使不定义形参,也可以通过arguments来使用实参 |
arguments中有一个属性callee表示当前执行的函数对象 |
function test() {
var s = "";
for (var i = 0; i < arguments.length; i++) {
alert(arguments[i]);
s += arguments[i] + ",";
}
return s;
}
test("name", "age");
输出结果: name,age
作用域简单来说就是一个变量的作用范围。 在JS中作用域分成两种:
1.全局作用域
直接在SCRIPT标签中编写的代码都运行在全局作用域中 |
---|
全局作用域在打开页面时创建,在页面关闭时销毁 |
全局作用域中有一个全局对象window,window对象由浏览器提供,它代表的是整个的浏览器的窗口,可以在页面中直接使用 |
在全局作用域中创建的变量都会作为window对象的属性保存 |
在全局作用域中创建的函数都会作为window对象的方法保存 |
在全局作用域中创建的变量和函数可以在页面的任意位置访问 |
在函数作用域中也可以访问到全局作用域的变量 |
尽量不要在全局中创建变量 |
2.函数作用域
函数作用域是函数执行时创建的作用域,每次调用函数都会创建一个新的函数作用域 |
---|
函数作用域在函数执行时创建,在函数执行结束时销毁 |
调用开辟内存,函数执行结束,释放内存 |
在函数作用域中能使用全局作用域中的变量;在全局作用域中无法使用函数作用域中的变量 |
当在函数作用域中使用一个变量时,它会先在自身作用域中寻找 如果找到了则直接使用,如果没有找到则到上一级作用域中寻找 如果找到了则使用,找不到则继续向上找,直到找到全局作用域 如果全局作用域依然没有找到,则会报错ReferenceError |
在函数中用var声明的变量,是局部变量;在函数外用var声明的变量是全局变量 |
3.变量的声明提前
在全局作用域中,使用VAR关键字声明的变量会在所有的代码执行之前被声明,但是不会赋值 |
---|
注;在执行前,浏览器会扫描var关键字,若有则使变量地位提升至最开头 |
所以我们可以在变量声明前使用变量。但是不使用var关键字声明的变量不会被声明提前 |
在函数作用域中,也具有该特性,使用var关键字声明的变量会在函数所有的代码执行前被声明 |
如果没有使用var关键字声明变量,则变量会变成全局变量(函数作用域中) |
4.函数的声明提前
在全局作用域中,使用函数声明创建的函数(FUNCTION FUN(){}),会在所有的代码执行之前被创建 |
---|
我们可以在函数声明前去调用函数,但是使用函数表达式(var fun = function(){})创建的函数没有该特性 |
在函数作用域中,使用函数声明创建的函数,会在所有的函数中的代码执行之前就被创建好了 |
2、构造函数的特点
构造函数是专门用来创建对象的函数 |
---|
一个构造函数我们也可以称为一个类 |
通过一个构造函数创建的对象,我们称该对象是这个构造函数的实例 |
通过同一个构造函数创建的对象,我们称为一类对象 |
构造函数就是一个普通的函数,只是他的调用方式不同 |
如果直接调用,它就是一个普通函数 |
如果使用new来调用,则它就是一个构造函数 |
3、构造函数的执行流程
构造函数的执行流程: |
---|
1.创建一个新的对象 |
2.将新的对象作为函数的上下文对象(this) |
3.执行函数中的代码 |
4.将新建的对象返回 |
4、instanceof用法
INSTANCEOF 用来检查一个对象是否是一个类的实例 |
---|
语法:对象 instanceof 构造函数 |
如果该对象是构造函数的实例,则返回true,否则返回false |
var per2;
var per = new Person("xiaoming");
console.log(per2 instanceof Person);//false
Object是所有对象的祖先,所以任何对象和Object做instanceof都会返回true
1、什么是原型,原型是如何产生的
创建一个函数以后,解析器都会默认在函数中添加一个属性PROTOTYPE |
---|
![]() |
prototype属性指向的是一个对象,这个对象我们称为原型对象。 当函数作为构造函数使用,它所创建的对象中都会有一个隐含的属性执行该原型对象,可以通过___proto___来访问 |
function Fun(){
};
var fun1 = new Fun();
var fun2 = new Fun();
console.log(Fun.prototype == fun1.__proto__);
2、为什么要使用原型
当在构造函数中添加方法时,每创建一个对象,都新增加一个方法,造成内存和性能的浪费(实例的方法具有唯一性)
因此,需要把重复的方法提取出来,放在一个公有的地方
(注:若将方法放在全局作用域,会污染全局作用域的命名空间,使代码缺少封装性)
function Fun(){
this.sayName = function(){
console.log("今天天气真好啊!");
};
}
var fun1 = new Fun();
var fun2 = new Fun();
fun1.sayName();
fun2.sayName();
console.log(fun1.sayName === fun2.sayName);//false
//说明每个对象具有不同的方法
3、原型对象的特点
4、如何使用原型对象
我们可以将对象中共有的属性和方法统一添加到原型对象中, 这样我们只需要添加一次,就可以使所有的对象都可以使用
Fun.prototype.sayName = function(){
console.log("今天天气真好啊!");
}
向原型对象中添加属性
Fun.prototype.name = "我是原型中的名字";
更多详情,请阅读以下网址(讲的清楚详细) |
---|
(68条消息) JavaScript中原型对象的彻底理解做人要厚道2013的博客-CSDN博客原型对象 |
帮你彻底搞懂JS中的prototype、proto与constructor(图解)码飞CC的博客-CSDN博客_doc.configuration.prototypeid js |
当我们直接在页面中打印一个对象时,实际上是输出的对象
如果我们希望输出对象的toString()返回值,可以为对象添加一个toString()方法
function Person(name,age,gender){
this.name = name;
this.age = age;
this.gender = gender;
}
//修改Person原型的toString
Person.prototype.toString = function(){
return `Person[name=${this.name},age=${this.age},gender=${this.gender}]`;
};
var per = new Person("孙悟空",18,"男");
var per2 = new Person("猪八戒",19,"男");
console.log(per.toString());
console.log(per2);
1、为什么会产生垃圾? |
---|
当一个对象没有任何的变量或属性对它进行引用,此时我们将永远无法操作该对象,此时这种对象就是一个垃圾 |
2、垃圾带来的危害 |
占用大量的内存空间,导致程序运行变慢 |
3、如何解决垃圾 |
垃圾回收的机制 |
在JS中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,我们不需要也不能进行垃圾回收的操作 |
我们需要做的只是要将不再使用的对象设置null即可 |
数组是一个对象 |
---|
存储效率比普通对象要高 |
数组中保存的内容我们称为元素 |
数组使用索引(index)来操作元素 |
索引指由0开始的整数 |
如果读取不存在的索引,会返回undefined |
数组中的元素可以是任意的数据类型(基本数据类型、对象、函数、数组) |
var arr = [{name:"小美",age:18}] |
a、创建数组
//1、创建数组对象
var arr = new Array(); arr[索引] = 值; arr[索引] = 值; arr[索引] = 值;
//使用构造函数创建数组时,也可以同时添加元素(元素作为参数传递)var arr = new Array(10,"hello",null); console.log(arr);//arr[10,"hello",null]; var arr = new Array(10);//表示创建了一个长度为10的数组
//2、使用字面量创建数组
var arr = [];
b、向数组中添加元素
$$
语法;数组对象[索引] = 值;
$$
arr[0] = 123;
arr[1] = "hello";
c、创建数组时直接添加元素
$$
语法: var\ arr = [元素1,元素2....元素N];
$$
例子:
var arr = [123,"hello",true,null];
d、获取和修改数组的长度(length)
获取长度: 数组.length length获取到的是数组的最大索引+1 对于连续的数组,length获取到的就是数组中元素的个数
修改数组的长度: 数组.length = 新长度 如果修改后的length大于原长度,则多出的部分会空出来 如果修改后的length小于原长度,则原数组中多出的元素会被删除
向数组的最后添加元素: 数组[数组.length] = 值;
//数组中存放数组
var arr = [[1,2,3],[4,5,6],[7,8,9]];
FUNCTIONNAME | FUNCTION | USAGE |
---|---|---|
push() | 用来向数组的末尾添加一个或多个元素,并返回数组新的长度 | 数组.push(元素1,元素2,元素N); |
var arr = ["孙悟空","猪八戒","沙和尚"]; arr.push("唐僧","白龙马"); console.log(arr.length);//5 | ||
pop() | 用来删除数组的最后一个元素,并返回被删除的元素 | 语法:数组.pop(); |
var result = arr.pop(); console.log(result); | ||
unshift() | 向数组的开头添加一个或多个元素,并返回数组的新的长度 | 数组.unshift(元素1...元素n); |
arr.unshift("白龙马","唐僧"); | ||
shift() | 删除数组的开头的一个元素,并返回被删除的元素 | 数组.shift(); |
arr.shift(); | ||
reverse() | 可以用来反转一个数组,它会对原数组产生影响 | 数组.reverse(); |
concat() | 可以连接两个或多个数组,它不会影响原数组,而是新数组作为返回值返回 | |
语法:数组1.concat(数组2,数组3...); | ||
console.log(arr.concat(arr2,arr3,"牛魔王")); | ||
1、作用: 可以从已有的数组中返回选定的元素 2、语法: arrayObject.slice(start,end) 3、参数: start 必须。 规定从何处开始选取。 若是负数,则从数组尾部开始选取 end 可选。 规定从何处结束选取。 可以是负数,不选则则一直截取到最后 4、返回值:返回一个新的数组,从start到end(不包括该元素) 5、参数可以传递一个负值,如果是负值,则从后往前数 -1:倒数第一个 eg:var arr = [1,2,3,4,5,6,7,0]; var result = arr.slice(3,5); console.log(result);//[4,5] console.log(arr.slice(4));//[5,6,7,0] console.log(arr.slice(4,-1));//[5,6,7] console.log(arr.slice(4,-3));//[5]
作用:可以用来删除数组中指定元素,并使用新的元素替换 该方法会将删除的元素封装到新数组中作为返回值返回 使用splice()会影响到原数组 参数: 1.必须,删除的开始位置的索引 2.可选,删除的数量 3.可选,三个以后,都是替换的元素,这些元素将会插入到开始位置索引的前边
var arr = [1,2,3,4,5,6,7,0]; var result2 = arr.splice(3,2,123); console.log(arr);//[1,2,3,123,6,7,0] console.log(result2);//[4,5]
作用:可以将一个数组转换为一个字符串 参数: 需要一个字符串作为参数,这个字符串将会作为连接符来连接数组中的元素,如果不指定连接符则默认使用 如:join("*"),join("^") 该方法不会对原数组产生影响,而是将转换后的字符串作为结果返回var arr = ["孙悟空","猪八戒","沙悟净","唐僧"]; var result = arr.join("-"); console.log(typeof result); //string console.log(result); //孙悟空-猪八戒-沙悟净-唐僧 console.log(arr); //["孙悟空","猪八戒","沙悟净","唐僧"]
作用:用于把Array的某些元素过滤掉,然后返回剩下的元素 参数: 需要一个回调函数,回调函数可以接收3个参数 1、element:表示Array的某个元素 2、index:元素的位置 3、self:数组本身var arr = ['A', 'B', 'C']; var r = arr.filter(function (element, index, self) { console.log(element); // 依次打印'A', 'B', 'C' console.log(index); // 依次打印0, 1, 2 console.log(self); // self就是变量arr return true; });
利用filter,可以巧妙地去除Array的重复元素:var arr = ['apple', 'strawberry', 'banana', 'pear', 'apple', 'orange', 'orange', 'strawberry']; r = arr.filter(function (element, index, self) { return self.indexOf(element) === index; }); console.log(r.toString()); //apple,strawberry,banana,pear,orange
indexOf(element,startLocation);返回某个指定的字符串值在字符串中首次出现的位置,如果没找到则返回-1。
1、作用: |
---|
可以对一个数组中的内容进行排序,默认是按照Unicode编码进行排序 |
2、是否影响原数组: |
影响,调用以后,会直接修改原数组 |
3、可以指定排序的规则,方法: |
需要一个回调函数作为参数,回调函数中需要定义两个形参 |
浏览器将会分别使用数组中的元素作为实参去调用回调函数 |
4、即使对于纯数字的数组,使用sort()排序时,也会按照Unicode编码来排序,因此对数字进行排序时,可能会得到错误的结果 |
5、使用哪个元素调用不确定,但是肯定的是在数组中,a一定在b前边 |
浏览器会根据回调函数的返回值来决定元素的顺序, 如果返回一个大于0的值,则元素会交换位置 如果返回一个小于0的值,则元素位置不变 如果返回一个0,则认为两个元素相等,也不交换位置 如果需要升序排列,则返回 a-b 如果需要降序排列,则返回b-afunction compare(a,b){ //升序排列 //return a-b; //降序排列 return b-a; } let values = [0,5,1,2,10]; values.sort(compare); alert(values);
会影响原数组的方法: |
---|
push(),pop() |
unshift(),shift() |
reverse() |
splice() |
sort() |
遍历数组就是将数组中元素都获取到 一般情况我们都是使用for循环来遍历数组
for(var i=0 ; i<数组.length ; i++){
//数组[i];
}
使用forEach()方法来遍历数组(不兼容IE8)
数组.forEach(function(value , index , obj){
});
var arr = [1,2,3"hello","nice","day"];
arr.forEach(function(value,index,obj){
console.log(value);
});
FOREACH()方法需要一个回调函数作为参数 |
---|
回调函数(callback):传递给另一个函数作为参数的函数(使用回调函数进行异步编程) |
数组中有几个元素,回调函数就会被调用几次 |
每次调用时,都会将遍历到的信息以实参的形式传递进来,可以定义形参来获取这些信息 |
value:正在遍历的元素 |
index:正在遍历元素的索引 |
obj:被遍历对象 |
在JS中为我们提供了三个包装类: String() 、Boolean() 、Number() 通过这三个包装类可以创建基本数据类型的对象 例子:
var num = new Number(2);
var str = new String("hello");
var bool = new Boolean(true);
但是在实际应用中千万不要这么干。三个包装类的是给后台使用的,比如浏览器,当我们调用比如字符串的方法时,后台会临时通过包装类来创建对象,然后通过对象调用方法,完成之后就会立即销毁
当我们去操作一个基本数据类型的属性和方法时,
解析器会临时将其转换为对应的包装类,然后再去操作属性和方法,
操作完成以后再将这个临时对象进行销毁。
var str = 'sunwukong' // string 基本类型
var s2 = str.charAt(0)
console.log(s2) // s
console.log(str) // sunwukong
实际上在执行 var s2 = str.charAt(0) 这行代码时,后台做了很多工作: 代码说明如下: var _str = new String('sunwukong') // 1.找到对应的包装类,然后通过包装类临时创建一个和基本类型值相同的对象 var s2 = _str.charAt(0) // 2.然后这个对象就可以调用包装对象下的方法,并且返回给 s2 _str = null // 3.最后自动销毁这个临时创建的对象
日期的对象,在JS中通过Date对象来表示一个时间
创建一个Date对象: 创建一个当前的时间对象
var d = new Date();
console.log(d);
//输出的的是当前执行代码的时间
//Sat Mar 26 2022 20:23:14 GMT+0800 (中国标准时间)
创建一个指定的时间对象 **需要在构造函数中传递一个表示时间的字符串作为参数** **日期格式:月/日/年 时:分:秒**
var d = new Date("月/日/年 时:分:秒");
var d1 = new Date("03/26/2022 20:33:10");
console.log(d1);
方法:
NAME | |
---|---|
getDate() | 当前日期对象是几日(1-31) |
getDay() | 返回当前日期对象时周几(0-6) 0 :周日, 1 :周一 ... |
getMonth() | 返回当前日期对象的月份(0-11) 0 :一月, 1 :二月 ... |
getFullYear() | 从 Date 对象以四位数字返回年份。 |
getHours() | 返回 Date 对象的小时 (0 ~ 23)。-1:前一天的最后一个小时 24:第二天的第一个小时 |
getMinutes() | 返回 Date 对象的分钟 (0 ~ 59)。-1:前一小时第一分钟 60:下一小时的第一分钟 |
getSeconds() | 返回 Date 对象的秒数 (0 ~ 59)。 |
getMilliseconds() | 返回 Date 对象的毫秒(0 ~ 999)。 |
getTime() | 返回创建当前日期对象时的时间戳 |时间戳,指的是从1970年月1日 0时0分0秒,到现在时间的毫秒数 计算机底层保存时间都是以时间戳的形式保存的。 |
Date.now() | 可以获取当前代码执行时的时间戳(var d = Date.now();测试代码的执行时间) |
setHours() | 设置 Date 对象中的小时 (0 ~ 23),语法:Date.setHours(hour,min,sec,millisec);返回值是一个时间戳 |
getTime()与Date.now()
console.time('time');
for (var i = 0; i < 10000; i++) {
let a = new Date().getTime();
}
console.timeEnd('time');
//time: 2.47998046875 ms
console.time('date');
for (var i = 0; i < 10000; i++) {
let b = Date.now();
}
console.timeEnd('date');
//date: 1.5029296875 ms
//1、getTime是原型上的方法Date.prototype.getTime(),而now是Date对象本身的方法Date.now()
var d = new Date();
d.getTime() //获取的是创建d时的毫秒数,不会随时间的增加而增加
Math属于一个工具类,它不需要我们创建对象,它里边封装了属性运算相关的常量和方法,我们可以直接使用它来进行数学运算相关的操作
方法:
NAME | |
---|---|
Math.PI 常量,圆周率 | |
Math.abs() 绝对值运算 | |
Math.ceil() 向上取整 | |
Math.floor() 向下取整 | |
Math.round() 四舍五入取整 | |
Math.random() Math.random():生成一个0-1([0,1))之间的随机数 | |
生成一个x-y之间的随机整数:Math.round(Math.random()*(y-x)+x); | |
Math.pow(x,y) 求x的y次幂 | |
Math.sqrt() 对一个数进行开方 | |
Math.max() 求多个数中最大值 | |
Math.min() 求多个数中的最小值 | |
注:Math.abs()、Math.ceil()、Math.floor()、Math.round()...将会返回一个新的值,不会影响原变量
字符串是一种类数组
使用ES6中的字符串新方法: String.padStart(maxLength, fillString='') //在String前面填充 or String.padEnd(maxLength, fillString='') //在String后面填充 来填充字符串;
const str1 = '5';
console.log(str1.padStart(2, '0'));
// expected output: "05"
const fullNumber = '2034399002125581';
const last4Digits = fullNumber.slice(-4);
const maskedNumber = last4Digits.padStart(fullNumber.length, '*');
console.log(maskedNumber);
// expected output: "************5581"
方法 | |||
---|---|---|---|
length | 获取字符串的长度 | str.length; | |
charAt() | 根据索引获取指定的字符 | str.charAt(0-str.length-1) | |
charCodeAt() | 根据索引获取指定的字符编码 | str.charCodeAt(0-str.length-1) | |
String.fromCharCode() | 根据字符编码获取字符 | String.fromCharCode(0x1234) | |
concat() | 连接字符串 | str.concat(str2...) | |
indexOf() | 给定一个参数:要搜索的子字符串,搜索整个调用字符串,并返回指定子字符串第一次出现的索引。 | str.indexOf("h",5) | |
lastIndexOf() | 从后往前检索一个字符串中指定内容,并返回第一次出现的索引 | str.lastIndexOf("h") | |
indexOf(),lastIndexOf()需要一个字符串作为参数,这个字符串就是要检索的内容, 如果找到该内容,则会返回其第一次出现的索引,如果没有找到则返回-1 参数1:子串 参数2:开始查找的位置 | |||
slice() | 可以从一个字符串中截取指定的内容,并将截取到内容返回,不会影响原变量 |
||
参数1:截取开始的位置(包括开始) 参数2:截取结束的位置(不包括结束) str.slice(参数1,参数2) | |||
可以省略第二个参数,如果省略则一直截取到最后 str.slice(参数1...) | |||
可以传负数,如果是负数则从后往前数 | |||
substr() | substr() 和slice()基本一致,但它第二个参数不是索引,而是截取的数量 | str.substr(位置,数量) | |
substring() | substring() 和slice()基本一致,但不能接受负值作为参数,如果设置一个负值,则会自动修正为0 | substring()中如果第二个参数小于第一个,自动调整位置 | |
toLowerCase() | 将字符串转换为小写并返回 | str.toLowerCase() | |
toUpperCase() | 将字符串转换为大写并返回 | "hello world".toUpperCase() |
1、什么是正则表达式
正则表达式用来定义一些字符串的规则 计算机可以根据这些规则来判断一个字符串是否符合规则 //将一个字符串中符合规则的内容提取出来// 类型:Object
2、创建正则表达式
$$
var reg = new RegExp("正则表达式","匹配模式")
$$
注意:使用构造函数时,由于它的参数是一个字符串,而 \ 是字符串中转义字符,如果要使用\则需要使用\\来代替`
var reg = new RegExp('a'); console.log(reg.test('asdfree'));//true
参数1, 正则表达式
参数2,匹配模式
i:忽略大小写(ignore)
g:全局匹配模式(默认为1次)(global)
在全局匹配模式下,正则表达式会对指定要查找的字符串执行多次匹配
设置匹配模式时,可以都不设置,也可以设置1个,也可以全设置,设置时没有顺序要求
3、使用字面量来创建正则表达式
语法:
var 变量 = /正则表达式/匹配模式;
(匹配模式可以多个一起写:/gi)
eg:
var reg = /a/i;
4、正则语法:
正则语法 | ||
| | 或 | a|b == [ab] |
[ ] | 或 | |
[^ ] | 除了 | [^0-9]([12]false [12a]true) |
[x-y] | x的ascii到y的ascii码之间的值 | |
[a-z] | 小写字母 | [e-i] |
[A-Z] | 大写字母 | |
[A-z] | 任意字母 | |
[0-9] | 任意数字 | |
元符号 | ||
\. | . 表示任意字符 | 表示 . |
\\ | \作为转义字符 | 表示 \ |
\w | 任意字母、数字、下划线 | 等价于[A-z0-9_] |
\W | 除了字母、数字、下划线 | 除了[ ^A-z0-9_] |
\d | 任意的数字 | 等价于 [0-9] |
\D | 除了数字 | <=> [ ^0-9] |
\s | 空格 | |
\S | 除了空格 | |
\b | 单词边界 | |
\B | 除了单词边界 | |
量词 | ||
通过量词可以设置一个内容出现的次数 | ||
量词只对它前边的一个内容起作用 | ||
{n} | 正好出现n次 | a{n} |
{m,n} | 出现m-n次 | a{m,n} |
{m,} | m次以上 | a{m,} |
n+ | 匹配至少一个n的字符串 | 相当于{1,} |
n* | 匹配0个或多个n的字符串 | 相当于{0,} |
n? | 只匹配*前面一个 匹配0个或1个n的字符串 |
相当于{0,1} |
边界表达式 | ||
^ | 正则开始 | reg = /^a/ |
$ | 正则结束 | reg = /b$/ |
注意结束前一个才是结束匹配 | ||
如果在正则表达式中同时使用^ $字符串完全符合正则表达式 |
去掉两端的空格
var s = " f afa "; s = s.replace(/^\s*|\s*$/g,"");
.*与.*?
.*:贪婪模式
.*?:非贪婪模式
*?:重复任意次,但尽可能少重复
后面加?,表示减少次数(?=pattern) :表示获取pattern匹配值
()表示将(和)之间的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域(一个正在表达式中最多可以保存9个),它们可以用\1和\9的符号来引用
test()
作用: 检查一个字符串是否符合正则表达式 如果符合返回true,否则返回false 语法: new RegExp('字符串1').test('字符串2') eg:
new RegExp('a').test("abc");//true
split()
作用: 可以根据指定内容将一个字符串拆分为一个数组 #正则分割字符串 参数: 需要一个字符串作为参数,将会根据字符串去拆分数组 可以接收一个正则表达式,此时会根据正则表达式去拆分数组 eg:
('23345d7rtf7eg74gue38').split(/[A-z]/); //['23345','7','','','7','','74','','','38']
match()
作用: 可以根据正则表达式,从一个字符串中将符合条件的内容提取出来 默认情况下我们的match只会找到第一个符合要求的内容,找到以后就停止检索 #我们可以设置正则表达式为全局匹配模式,这样就会匹配到所有的内容 可以为一个正则表达式设置多个匹配模式,且顺序无所谓 match()会将匹配到的内容封装到一个数组中返回,即使只查询到一个结果 eg:var str = '1a2b3c4e5d6f7g'; result = str.match(/[0-9]/g); console.log(result); //['1', '2', '3', '4', '5', '6', '7']
replace()
作用: 可以将字符串中指定内容替换为新的内容 参数: 1.被替换的内容,可以接收一个正则表达式作为参数 2.新的内容, 空串则为删除 "" 默认只会替换第一个 eg1:
var str = '12sd34nfu7dg5sv8dwndg'; var result = str.replace(/[a-z]/g,'@'); console.log(result); //12@@34@@@7@@5@@8@@@@@
eg2:var result2 = 'hello. --a.. . ,, day n i ce'.replace(/[,-\.\s]/g,''); console.log(result2); //helloadaynice
search()
作用: 可以搜索字符串中是否含有指定内容 如果搜索到指定内容,则会返回第一次出现的索引 如果没有搜索到则返回-1 它可以接受一个正则表达式作为参数,然后会根据正则表达式去检索字符串 serach()只会查找第一个,即使设置全局匹配也没用 eg:var str = "123ASDzxc"; var result2 = str.search(/[0-9][2-3][A-z]/); console.log(result2);//1
1、校验数字的表达式
汉字:^[\u4e00-\u9fa5]{0,}$
英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
长度为3-20的所有字符:^.{3,20}$
由26个英文字母组成的字符串:^[A-z]+$
由26个大写英文字母组成的字符串:^[A-Z]+$
由26个小写英文字母组成的字符串:^[a-z]+$
由数字和26个英文字母组成的字符串:^[A-z0-9]+$
由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$
中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
可以输入含有^%&',;=?$\"等字符:[^%&',;=?$\x22]+
禁止输入含有~的字符:[^~\x22]+
2、校验字符的表达式
数字:^[0-9]*$
n位的数字:^\d{n}$
至少n位的数字:^\d{n,}$
m-n位的数字:^\d{m,n}$
零和非零开头的数字:^(0|[1-9][0-9]*)$
非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})?$
正数、负数、和小数:^(\-|\+)?\d+(\.\d+)?$
有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
非零的正整数:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
非零的负整数:^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
非负整数:^\d+$ 或 ^[1-9]\d*|0$
非正整数:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
非负浮点数:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
非正浮点数:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
正浮点数:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
负浮点数:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
浮点数:^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
3、特殊需求表达式
Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
手机号码:^(13[0-9]|14[0-9]|15[0-9]|16[0-9]|17[0-9]|18[0-9]|19[0-9])\d{8}$ (由于工信部放号段不定时,所以建议使用泛解析 ^([1][3,4,5,6,7,8,9])\d{9}$)
电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$
国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}
18位身份证号码(数字、字母x结尾):^((\d{18})|([0-9x]{18})|([0-9X]{18}))$
帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$
#强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
日期格式:^\d{4}-\d{1,2}-\d{1,2}
一年的12个月(01~09和1~12):^(0?[1-9]|1[0-2])$
一个月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$
钱的输入格式:
1. 有四种钱的表示形式我们可以接受:"10000.00" 和 "10,000.00", 和没有 "分" 的 "10000" 和 "10,000":^[1-9][0-9]*$
2. 这表示任意一个不以0开头的数字,但是,这也意味着一个字符"0"不通过,所以我们采用下面的形式:^(0|[1-9][0-9]*)$
3. 一个0或者一个不以0开头的数字.我们还可以允许开头有一个负号:^(0|-?[1-9][0-9]*)$
4. 这表示一个0或者一个可能为负的开头不为0的数字.让用户以0开头好了.把负号的也去掉,因为钱总不能是负的吧.下面我们要加的是说明可能的小数部分:^[0-9]+(.[0-9]+)?$
5. 必须说明的是,小数点后面至少应该有1位数,所以"10."是不通过的,但是 "10" 和 "10.2" 是通过的:^[0-9]+(.[0-9]{2})?$
6. 这样我们规定小数点后面必须有两位,如果你认为太苛刻了,可以这样:^[0-9]+(.[0-9]{1,2})?$
7. 这样就允许用户只写一位小数.下面我们该考虑数字中的逗号了,我们可以这样:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$
8. 1到3个数字,后面跟着任意个 逗号+3个数字,逗号成为可选,而不是必须:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$
备注:这就是最终结果了,别忘了"+"可以用"*"替代如果你觉得空字符串也可以接受的话(奇怪,为什么?)最后,别忘了在用函数时去掉去掉那个反斜杠,一般的错误都在这里
xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
中文字符的正则表达式:[\u4e00-\u9fa5]
双字节字符:[^\x00-\xff] (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
空白行的正则表达式:\n\s*\r (可以用来删除空白行)
HTML标记的正则表达式:<(\S*?)[^>]*>.*?|<.*? /> (网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力)
首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)
腾讯QQ号:[1-9][0-9]{4,} (腾讯QQ号从10000开始)
中国邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为6位数字)
IP地址:\d+\.\d+\.\d+\.\d+ (提取IP地址时有用)
IP地址:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)) (由@飞龙三少 提供,感谢共享)
Document Object Model
文档对象模型,通过DOM可以来任意来修改网页中各个内容
文档
文档指的是网页,一个网页就是一个文档
对象
对象指将网页中的每一个节点都转换为对象
转换完对象以后,就可以以一种纯面向对象的形式来操作网页了
模型
模型用来表示节点和节点之间的关系,方便操作页面
节点(Node)
节点是构成网页的最基本的单元,网页中的每一个部分都可以称为是一个节点
虽然都是节点,但是节点的类型却是不同的
常用的节点
文档节点 (Document),代表整个网页
元素节点(Element),代表网页中的标签
属性节点(Attribute),代表标签中的属性
文本节点(Text),代表网页中的文本内容
文档Document -表示整个HTML网页文档 对象Object -表示将网页中的每一部分都转换为一个对象 模型Model -表示对象之间的关系
1、document对象
WINDOW对象的属性 |
---|
代表整个网页,可以在页面中直接使用 |
2、model
网页的标题
超链接
3、节点
节点node,是构成网页的最基本组成部分,网页中的每一部分都可以称为是一个节点。
比如:html标签、属性、文本、注释、整个文档等都是一个节点。
文档节点:整个HTML文档 |
---|
元素节点:HTML文档中的HTML标签 |
属性节点:元素的属性 |
文本节点:HTML标签中的文本内容 |
节点的属性:
1、获取DOM对象
DOCUMENT查询方法: | |
---|---|
根据元素的id属性查询一个元素节点对象: | document.getElementById("id属性值"); |
根据元素的name属性值查询一组元素节点对象: | document.getElementsByName("name属性值"); |
作用:可以获取带有指定名称的集合 | |
根据标签名来查询一组元素节点对象:(类数组) | document.getElementsByTagName("标签名"); |
2、获取元素节点的属性
元素的属性: 读取元素节点的的属性: 语法:元素节点.属性名 alert(ele.type); 修改元素节点的属性: 语法:元素节点.属性名 = 属性值 ele.type = 'submit'; 例子:let ele = doucument.getElementsByTagName('input');
ele.name ele.id ele.value ele.className 注意:class属性不能采用这种方式, 读取class属性时需要使用 元素节点.className innerHTML 使用该属性可以获取或设置元素内部的HTML代码
3、innerHTML和innerText
这两个属性并没有在DOM标准定义,但是大部分浏览器都支持这两个属性 1、作用: innerHtml:获取标签内部的HTML代码,包括HTML标签 浏览器会解析设置的值为相应的DOM树 innerText:获取标签内部的HTML代码,自动去除HTML标签 outerHTML:除了包含innerHTML全部内容外,还包含对象标签本身 2、读取标签内部的文本内容 如果使用这两个属性来设置标签内部的内容时,没有任何区别的 3、还可以使用innerHTML来修改内容document.getElementById('X').innerHTML = '要修改的内容'
4、innerHTML对于自结束标签无意义 5、innerHTML所有浏览器都支持,innerText Firefox不支持
4、通过具体的元素节点来查询
通过标签名查询当前元素的指定后代元素 1、先找到父节点 2、通过父节点去找子节点 元素节点.getElementsByTagName()[0] 元素节点.getElementsByClassName()[0] element.getElementById(); 子节点包括标签元素中的文本,子元素只包含标签元素 元素节点.childNodes 获取当前元素的**所有子节点** **会获取到空白的文本子节点** childNodes属性会获取包括文本节点在内的所有节点 根据DOM标签标签间空白也会当成文本节点 注意:在IE8及以下的浏览器中,不会将空白文本当成子节点, 所以该属性在IE8中会返回4个子元素而其他浏览器是9个 获取指定子节点 元素节点.childNodes[i] ★元素节点.children 获取当前元素的**所有子元素** 获取指定元素 元素节点.children[i] 元素节点.firstChild 获取当前元素的**第一个子节点**,会获取到空白的文本子节点 元素节点.lastChild 获取当前元素的**最后一个子节点** ★元素节点.parentNode 获取当前元素的父元素 元素节点.previousSibling 获取当前元素的前一个兄弟节点(包括文本节点) ★元素节点.previousElementSibling获取前一个兄弟元素, IE8及以下不支持 元素节点.nextSibling 获取当前元素的后一个兄弟节点(包括文本节点) ★元素节点.nextElementSibling 获取当前元素的后一个兄弟元素 firstElementChild获取当前元素的第一个子元素 firstElementChild不支持IE8及以下的浏览器, 如果需要兼容他们尽量不要使用 lastElementChild获取当前元素的最后一个子元素 元素.firstChild.nodeValue获取当前元素第一个孩子节点(文本节点)的文本内容 /文档节点和元素节点的nodevalue是null
document.documentElement
**获取页面中html根元素**
//获取HTML根标签
let h = document.documentElement;
console.log(h);
document.body
获取页面中的body元素
document的属性body保存body的引用
获取body标签 body 是一个[object HTMLCollection]
let all = document.getElementsByTagName('body')[0];
console.log(all);
let body = document.body;
console.log(body);
document.all **获取页面中的所有元素结点**,相当于document.getElementsByTagName("*"); 获取页面中所有的元素结点
let All = document.all;
console.log(All);//返回一个类数组
let All2 = document.getElementsByTagName('*');
console.log(All2);
document.getElementsByClassName()
**根据元素的class属性值查询一组元素节点对象**
这个方法不支持IE8及以下的浏览器
document.querySelector()
**根据CSS选择器去页面中查询一个元素**
如果匹配到的元素有多个,则它会返回查询到的第一个元素
参数:选择器的字符串
/----------------------------------------
- 足球
- 篮球
- 乒乓
ll
//querySelector
let query = document.querySelector('.sport li');
console.log(query);
//...
document.querySelectorAll()
根据CSS选择器去页面中查询一组元素
会将匹配到所有元素封装到一个数组中返回,即使只匹配到一个
/---------------------------------------------
- 足球
- 篮球
- 乒乓
ll
//querySelectorAll
let query2 = document.querySelectorAll('.sport li');
console.log(query2);
//NodeList(3)[li,li,li]
方法 描述 | |
---|---|
createTextNode() | 创建文本节点 |
appendChild() | 把新的子节点添加到指定节点 |
removeChild() | 删除子节点 |
replaceChild() | 替换子节点 |
insertBefore() | 在指定的子节点前面插入新的子节点 |
createElement() | 创建元素节点 |
1、父节点.appendChild(子节点) 向父节点中添加指定的子节点 2、父节点.removeChild(子节点) 删除指定的子节点 #当不知道具体的父元素时,可以通过parentNode得到# 语法: 子节点.parentNode.removeChild(子节点) 3、父节点.replaceChild(新节点,旧节点) 使用一个新的节点去替换旧节点 4、父节点.insertBefore(新节点,旧节点) 将一个新的节点插入到旧节点的前边 5、document.createElement("TagName") 可以用于创建一个元素节点对象, 它需要一个标签名作为参数,将会根据该标签名创建元素节点对象,并将创建好的对象作为返回值返回 6、document.createTextNode("textContent") 可以根据文本内容创建一个文本节点对象
以上方法,实际就是改变了相应元素(标签)的innerHTML的值。
myClick("btn07",function(){
//向city中添加广州
var city = document.getElementById("city");
/*
使用innerHTML也可以完成DOM的增删改的相关操作
一般我们会两种方式结合使用
*/
//第一种、
city.innerHTML += "广州 ";
//第二种、
//创建一个li
var li = document.createElement("li");
//向li中设置文本
li.innerHTML = "广州";
//将li添加到city中
city.appendChild(li);
});
使用style属性来操作元素的内联样式
$$
读取内联样式: 语法:元素节点.style.样式名
$$
例子:
元素节点.style.width
元素节点.style.height
注意:如果样式名中带有''-'',则需要将样式名修改为驼峰命名法将-去掉,然后后面的字母改成大写
比如: backgroundcolor => backgroundColor
borderwidth => borderWidth
box1.style.backgroundColor ='red';
修改内联样式:
语法:
元素节点.style.样式名 = '样式值'
box1.style.width ='250px';
通过style修改和读取的样式都是内联样式,由于内联样式的优先级比较高,
所以我们通过JS来修改的样式,往往会立即生效,
//通过style修改的样式,是修改的内联样式
**但是如果样式中设置了!important,则内联样式将不会生效。** !important 作用:获取到最高的优先级(慎用)
正常浏览器 使用getComputedStyle()
getComputedStyle() 这个方法是window对象的方法,可以返回一个对象,这个对象中保存着当前元素生效样式 参数: 1.要获取样式的元素节点 2.可以传递一个伪元素,一般传null 例子: 获取元素的宽度
getComputedStyle(box , null)["width"];
通过该方法读取到样式都是只读的不能修改
IE8 使用currentStyle
currentStyle 语法: 元素节点.currentStyle.样式名 例子:
box.currentStyle["width"]
通过这个属性读取到的样式是只读的不能修改
实现兼容性
对象.属性不存在,不会报错,
如果直接寻找对象,(当前作用域到全局作用域)找不到会报错
/* * 定义一个函数,用来获取指定元素的当前的样式 * 参数: * obj 要获取样式的元素 * name 要获取的样式名 * *该方法会返回一个对象,对象中封装了当前元素对应的样式 * *可以通过(对象.样式名)|(对象[样式名])来读取样式 * *如果获取的样式没有设置,则会获取到真实的值,而不是默认值,比如:没有设置width,不会获取到auto,而是一个长度 */function getStyle(obj , name){ //对象.属性不存在,不会报错,如果直接寻找对象,(当前作用域到全局作用域)找不到会报错 if(window.getComputedStyle){ //正常浏览器的方式,具有getComputedStyle()方法 return getComputedStyle(obj , null)[name]; }else{ //IE8的方式,没有getComputedStyle()方法 return obj.currentStyle[name]; } //简写 //return window.getComputedStyle?getComputedStyle(obj , null)[name]:obj.currentStyle[name]; }
注意:以下样式都是只读的,未指明偏移量都是相对于当前窗口左上角
clientHeight 元素的可见高度,包括元素的内容区和内边距的高度 clientWidth 元素的可见宽度,包括元素的内容区和内边距的宽度 clientLeft 左边框的宽度 clientTop 上边框的宽度 #不需要带px,返回的是一个数字,可以直接进行计算 offsetHeight 整个元素的高度,包括内容区、内边距、边框 offfsetWidth 整个元素的宽度,包括内容区、内边距、边框 offsetParent 当前元素的定位父元素 离他最近的开启了定位的祖先元素,如果所有的元素都没有开启定位,则返回body offsetLeft offsetTop 当前元素和定位父元素之间的偏移量 offsetLeft水平偏移量 offsetTop垂直偏移量 scrollHeight scrollWidth 获取元素滚动区域的高度和宽度 (文档内容实际高度,包括超出视窗的溢出部分) 判断滚动条是否滚动到底 垂直滚动条 scrollHeight -scrollTop = clientHeight 水平滚动 scrollWidth -scrollLeft = clientWidth
可写
scrollTop scrollLeft 获取元素垂直和水平滚动条滚动的距离
scrollHeight、scrollTop、clientHeight三者的关系:
事件指的是用户和浏览器之间的交互行为。比如:点击按钮、关闭窗口、鼠标移动。。。 #我们可以为事件来绑定回调函数来响应事件
1.可以在标签的事件属性中设置相应的JS代码 例子:
//结构和行为耦合,不方便维护
2.可以通过为对象的指定事件属性设置回调函数的形式来处理事件 例子:
浏览器在加载一个页面时,是按照自上向下的顺序加载的,加载一行执行一行 |
---|
如果将js代码编写到页面的上边,当代码执行时,页面中的DOM对象还没有加载 |
此时将会无法正常获取到DOM对象,导致DOM操作失败 |
解决方式一: |
可以将js代码编写到body里边 |
将JS代码编写到页面的下部,可以在页面加载完成后,直接执行JS代码
解决方式二:
onload事件会在整个页面加载完成之后才触发 为Window绑定一个onload事件 该事件对应的响应函数将会在页面加载完成之后再执行 可以确保代码执行时,DOM对象已经加载完毕了 将js代码编写到window.onload = function(){}中 window.onload 对应的回调函数会在整个页面加载完毕以后才执行,
当响应函数被调用时,浏览器每次都会将一个事件对象作为实参传递进响应函数中,这个事件对象中封装了当前事件的相关信息,比如:鼠标的坐标,键盘的按键,鼠标的按键,滚轮的方向。。
可以在响应函数中定义一个形参,来使用事件对象,但是在IE8以下浏览器中事件对象没有作为实参传递,而是作为window对象的属性保存
例子:
元素.事件 = function(event){
event = event || window.event;
};
元素.事件 = function(e){
e = e || event;
};
获取到鼠标的坐标
clientX和clientY
用于获取鼠标在当前的可见窗口的坐标 div的偏移量,是相对于整个页面的
pageX和pageY
可以获取鼠标相对于当前页面的坐标
但是这个两个属性在IE8中不支持,所以如果需要兼容IE8,则不要使用
var left = event.clientX; v
ar top = event.clientY;
事件的冒泡指的是事件向上传导,当后代元素上的事件被触发时,将会导致其祖先元素上的同类事件也会触发。 事件的冒泡大部分情况下都是有益的,如果需要取消冒泡,则需要使用事件对象来取消 可以将事件对象的cancelBubble设置为true,即可取消冒泡 例子:
元素.事件 = function(event){
//解决事件对象的兼容性问题
event = event || window.event;
//在IE8中,响应函数被触发时,浏览器不会传递事件对象
在IE8及以上的浏览器中,是将事件对象作为window对象的属性保存的
event.cancelBubble = true;
};
事件委派:JS事件委托(事件代理) (biancheng.net)
指将事件统一绑定给元素的共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件。
事件委派是利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能
我们希望,只绑定一次事件,即可应用到多个的元素上,即使元素是后添加的
我们可以尝试将其绑定给元素的共同的祖先元素
target : event中的target表示的触发事件的对象
addEventListener() 通过这个方法也可以为元素绑定响应函数 参数: 1.事件的字符串,不要on 2.回调函数,当事件触发时该函数会被调用 3.是否在捕获阶段触发事件,需要一个布尔值,一般都传false
使用addEventListener()可以同时为一个元素的相同事件同时绑定多个响应函数, 这样当事件被触发时,响应函数将会按照函数的绑定顺序执行
这个方法不支持IE8及以下的浏览器
btn01.addEventListener("click",function(){
alert(1);
},false);
btn01.addEventListener("click",function(){
alert(2);
},false);
attachEvent()
在IE8中可以使用attachEvent()来绑定事件 参数: 1.事件的字符串,要on 2.回调函数
这个方法也可以同时为一个事件绑定多个处理函数, 不同的是它是后绑定先执行,执行顺序和addEventListener()相反
btn01.attachEvent("onclick",function(){
alert(1);
});
btn01.attachEvent("onclick",function(){
alert(2);
});
//定义一个函数,用来为指定元素绑定响应函数
/*
* addEventListener()中的this,是绑定事件的对象
* attachEvent()中的this,是window
* 需要统一两个方法this
*/
/*
* 参数:
* obj 要绑定事件的对象
* eventStr 事件的字符串(不要on)
* callback 回调函数
*/
function bind(obj , eventStr , callback){
if(obj.addEventListener){
//大部分浏览器兼容的方式
obj.addEventListener(eventStr , callback , false);
}else{
/*
* this是谁由调用方式决定
* callback.call(obj)
*/
//IE8及以下
obj.attachEvent("on"+eventStr , function(){
//在匿名函数中调用回调函数
callback.call(obj);
});
}
}
关于事件的传播网景公司和微软公司有不同的理解 微软公司认为事件应该是由内向外传播,也就是当事件触发时,应该先触发当前元素上的事件, 然后再向当前元素的祖先元素上传播,也就说事件应该在冒泡阶段执行。 网景公司认为事件应该是由外向内传播的,也就是当前事件触发时,应该先触发当前元素的最外层的祖先元素的事件, 然后在向内传播给后代元素
W3C综合了两个公司的方案,将事件传播分成了三个阶段
1.捕获阶段 在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件
2.目标阶段 事件捕获到目标元素,捕获结束开始在目标元素上触发事件
3.冒泡阶段 事件从目标元素向他的祖先元素传递,依次触发祖先元素上的事件
如果希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true 一般情况下我们不会希望在捕获阶段触发事件,所以这个参数一般都是false
IE8及以下的浏览器中没有捕获阶段
onmouseover 移入某元素就触发,移入或移出子元素将再次被触发 |
onmousemove 在绑定的元素上移动时,被触发 |
拖拽事件(onmousemove)
我是一段文字
滚轮事件:
onwheel都支持
键盘事件:
onkeydown 按键被按下
对于onkeydown来说如果一直按着某个按键不松手,则事件会一直触发 当onkeydown连续触发时,第一次和第二次之间会间隔稍微长一点,其他的会非常的快,这种设计是为了防止误操作的发生。
onkeyup 按键被松开
键盘事件一般都会绑定给一些可以获取到焦点的对象或者是document
keyCode
可以通过keyCode来获取按键的编码 通过它可以判断哪个按键被按下 除了keyCode,事件对象中还提供了几个属性
altKey
ctrlKey
shiftKey 这个三个用来判断alt ctrl 和 shift是否被按下
如果按下则返回true,否则返回false
console.log(event.keyCode);
//判断一个y是否被按下
//判断y和ctrl是否同时被按下
if(event.keyCode === 89 && event.ctrlKey){
console.log("ctrl和y都被按下了");
}
input.onkeydown = function(event) {
event = event || window.event;
//数字 48 - 57
//使文本框中不能输入数字
if(event.keyCode >= 48 && event.keyCode <= 57) {
//在文本框中输入内容,属于onkeydown的默认行为
//如果在onkeydown中取消了默认行为,则输入的内容,不会出现在文本框中
return false;
}
};
浏览器对象模型(browser object model)
BOM可以使我们通过JS来操作浏览器
在BOM中为我们提供了一组对象,用来完成对浏览器的操作
BOM对象
Window
代表的是整个浏览器的窗口,同时window也是网页中的全局对象
Navigator
代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器
Location
代表当前浏览器的地址栏信息,通过Location可以获取地址栏信息,或者操作浏览器跳转页面
History
代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录
由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页
而且该操作只在当次访问时有效
Screen
代表用户的屏幕的信息,通过该对象可以获取到用户的显示器的相关的信息
这些BOM对象在浏览器中都是作为window对象的属性保存的, 可以通过window对象来使用,也可以直接使用
代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器
由于历史原因,Navigator对象中的大部分属性都已经不能帮助我们识别浏览器了
一般我们只会使用userAgent来判断浏览器的信息, userAgent是一个字符串,这个字符串中包含有用来描述浏览器信息的内容, 不同的浏览器会有不同的userAgent
火狐的userAgent Mozilla5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko20100101 Firefox50.0
Chrome的userAgent Mozilla5.0 (Windows NT 6.1; Win64; x64) AppleWebKit537.36 (KHTML, like Gecko) Chrome52.0.2743.82 Safari537.36
IE8 Mozilla4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
IE9 Mozilla5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
IE10 Mozilla5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
IE11 Mozilla5.0 (Windows NT 6.1; WOW64; Trident7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; rv:11.0) like Gecko 在IE11中已经将微软和IE相关的标识都已经去除了,所以我们基本已经不能通过UserAgent来识别一个浏览器是否是IE了
alert(navigator.appName);
var ua = navigator.userAgent;
console.log(ua);
if(firefoxi.test(ua)){
alert("你是火狐!!!");
}else if(chromei.test(ua)){
alert("你是Chrome");
}else if(msiei.test(ua)){
alert("你是IE浏览器~~~");
}else if("ActiveXObject" in window){
alert("你是IE11,枪毙了你~~~");
}
对象可以用来操作浏览器向前或向后翻页
length
属性,可以获取到当成访问的链接数量
back()
可以用来回退到上一个页面,作用和浏览器的回退按钮一样
forward()
可以跳转下一个页面,作用和浏览器的前进按钮一样
go()
可以用来跳转到指定的页面
它需要一个整数作为参数
1:表示向前跳转一个页面 相当于forward()
2:表示向前跳转两个页面
-1:表示向后跳转一个页面
-2:表示向后跳转两个页面
该对象中封装了浏览器的地址栏的信息
如果直接打印location,则可以获取到当前地址栏的信息(当前页面的完整路径)
alert(location);
如果直接将location属性修改为一个完整的路径,或相对路径
则我们页面会自动跳转到该路径,并且会生成相应的历史记录
location = "http:www.baidu.com";
location = "01.BOM.html";
assign() 用来跳转到其他的页面,作用和直接修改location一样
reload() 用于重新加载当前页面,作用和刷新按钮一样
如果在方法中传递一个true,作为参数,则会强制清空缓存刷新页面
location.reload(true);
replace()
可以使用一个新的页面替换当前页面,调用完毕也会跳转页面
不会生成历史记录,不能使用回退按钮回退
setInterval() 定时调用
可以将一个函数,每隔一段时间执行一次
参数:
1.回调函数,该函数会每隔一段时间被调用一次
2.每次调用间隔的时间,单位是毫秒
返回值: 返回一个Number类型的数据 ,这个数字用来作为定时器的唯一标识
clearInterval() 可以用来关闭一个定时器
方法中需要一个定时器的标识作为参数,这样将关闭标识对应的定时器
clearInterval() 可以接收任意参数, 如果参数是一个有效的定时器的标识,则停止对应的定时器 如果参数不是一个有效的标识,则什么也不做
var num = 1;
var timer = setInterval(function() {
count.innerHTML = num++;
if(num == 11) {
//关闭定时器
clearInterval(timer);
}
}, 1000);
延时调用一个函数不马上执行,而是隔一段时间以后在执行,而且只会执行一次
延时调用和定时调用的区别,定时调用会执行多次,而延时调用只会执行一次
延时调用和定时调用实际上是可以互相代替的,在开发中可以根据自己需要去选择
var timer = setTimeout(function(){
console.log(num++);
},3000);
使用clearTimeout()来关闭一个延时调用
clearTimeout(timer);
#类的操作
通过style属性来修改元素的样式,每修改一个样式,浏览器就需要重新渲染一次页面。 这样的执行的性能是比较差的,而且这种形式当我们要修改多个样式时,也不太方便
我们希望一行代码,可以同时修改多个样式
我们可以通过修改元素的class属性来间接的修改样式。这样一来,我们只需要修改一次,即可同时修改多个样式,浏览器只需要重新渲染页面一次,性能比较好, 并且这种方式,可以使表现和行为进一步的分离
box.className += " b2"; //注意有空格,添加class属性
//定义一个函数,用来向一个元素中添加指定的class属性值
/*
* 参数:
* obj 要添加class属性的元素
* cn 要添加的class值
*
*/
function addClass(obj, cn) {
if (!hasClass(obj, cn)) {
obj.className += " " + cn;
}
}
/*
* 判断一个元素中是否含有指定的class属性值
* 如果有该class,则返回true,没有则返回false
*
*/
function hasClass(obj, cn) {
var reg = new RegExp("\\b" + cn + "\\b");
return reg.test(obj.className);
}
/*
* 删除一个元素中的指定的class属性
*/
function removeClass(obj, cn) {
//创建一个正则表达式
var reg = new RegExp("\\b" + cn + "\\b");
//删除class
obj.className = obj.className.replace(reg, "");
}
/*
* toggleClass可以用来切换一个类
* 如果元素中具有该类,则删除
* 如果元素中没有该类,则添加
*/
function toggleClass(obj , cn){
//判断obj中是否含有cn
if(hasClass(obj , cn)){
//有,则删除
removeClass(obj , cn);
}else{
//没有,则添加
addClass(obj , cn);
}
}
JavaScript Object Notation JS对象表示法
复合类型的值只能是数组或对象,不能是函数、正则表达式对象、日期对象。
原始类型的值只有四种:字符串、数值(必须以十进制表示)、布尔值和
null
(不能使用NaN
,Infinity
,-Infinity
和undefined
)。字符串必须使用双引号表示,不能使用单引号。
对象的键名必须放在双引号里面。
数组或对象最后一个成员的后面,不能加逗号。
JS中的对象只有JS自己认识,其他的语言都不认识
JSON就是一个特殊格式的字符串,这个字符串可以被任意的语言所识别, 并且可以转换为任意语言中的对象,JSON在开发中主要用来数据的交互
JSON和JS对象的格式一样,只不过JSON字符串中的属性名必须加双引号 ,其他的和JS语法一致
JSON分类:
1.对象 {} 2.数组 []
JSON中允许的值: 1.字符串 2.数值 3.布尔值 4.null 5.对象 6.数组
举例:
var arr = '[1,2,3,"hello",true]';
var obj2 = '{"arr":[1,2,3]}';
var arr2 ='[{"name":"孙悟空","age":18,"gender":"男"},{"name":"孙悟空","age":18,"gender":"男"}]';
json字符串 转换 js对象
JSON.parse()
可以将以JSON字符串转换为js对象
它需要一个JSON字符串作为参数,会将该字符串转换为JS对象并返回
var o = JSON.parse(json);
var o2 =JSON.parse(arr);
var obj3 = {name:"猪八戒" , age:28 , gender:"男"};
JS对象 转换 json字符串
JSON.stringify() -ify/fy,表示"使……化。
可以将一个JS对象转换为JSON字符串
需要一个js对象作为参数,会返回一个JSON字符串
var str = JSON.stringify(obj3);
console.log(str);
JSON这个对象在IE7及以下的浏览器中不支持,所以在这些浏览器中调用时会报错
只读的localStorage
属性允许你访问一个Document 源(origin)的对象 Storage;其存储的数据能在跨浏览器会话保留。localStorage
类似 sessionStorage,但其区别在于:存储在 localStorage
的数据可以长期保留;而当页面会话结束——也就是说,当页面被关闭时,存储在 sessionStorage
的数据会被清除 。
localStorage
中的键值对总是以字符串的形式存储。
存储的键值对总是以 UTF-16 DOMString 的格式所存储,其使用两个字节来表示一个字符。对于对象、整数 key 值会自动转换成字符串形式。
语法
myStorage = localStorage;
方法
setItem() 向本地增加一个记录
localStorage.setItem('myCat', 'Tom');
//key:keyValue
getItem() 读取localStorage项
let cat = localStorage.getItem('myCat');
removeItem() 移除localStorage项
localStorage.removeItem('myCat');
clear() 移除所有的localStorage项
// 移除所有
localStorage.clear();
存储在 sessionStorage
里面的数据在页面会话结束时会被清除。
// 保存数据到 sessionStorage
sessionStorage.setItem('key', 'value');
// 从 sessionStorage 获取数据
let data = sessionStorage.getItem('key');
// 从 sessionStorage 删除保存的数据
sessionStorage.removeItem('key');
// 从 sessionStorage 删除所有保存的数据
sessionStorage.clear();
返回值
一个Storage对象
eval()函数会将传入的字符串当做 JavaScript 代码进行执行,并将执行结果返回。如果返回值为空,则返回 undefined。
如果使用eval()执行的字符串中含有{},它会将{}当成是代码块 如果不希望将其当成代码块解析,则需要在字符串前后各加一个()
eval()这个函数的功能很强大,可以直接执行一个字符串中的js代码, 但是在开发中尽量不要使用,首先它的执行性能比较差,然后它还具有安全隐患 ,只作了解,不要使用
var str = '{"name":"孙悟空","age":18,"gender":"男"}';
var obj = eval("("+str+")");
\u四位编码
☠
⚀
copy() {
const input = document.createElement("input");
document.body.appendChild(input);
input.setAttribute("value",this.solution.code);
input.select();
if (document.execCommand("copy")) {
document.execCommand("copy");
// console.log("复制成功");
}
document.body.removeChild(input);
}
参考链接:
尚硅谷视频
MDN
菜鸟教程
w3school 在线教程
以及其中引用的链接