1.JavaScript入门
1.1简介
javascript简称js,是基于对象和事件驱动的客户端脚本语言。
ECMAScript5.0 ECMAScript6.0简称ES5 ES6
javascript和java有什么关系?
没有关系
雷锋和雷峰塔
仙女和仙女山
老婆和老婆饼
javascript能做什么?
网页特效
表单验证(正则)
游戏编写
编写Node
1.2javascript的引入方式
直接引入
<script>js代码</script>
<script type="text/javascript">js代码</script>
<script language="javascript">js代码</script>
外部引入
<script src="url地址"></script>
注意:外部引入的script标签内的代码不生效
js的引入位置:js可以在任意地方引入,除了title标签
建议将js代码放置在body的内容之后,如果放置在head中,若js代码过大,可能会导致一段时间的网页空白。
1.3js常见的几种输出方式
方式一:弹框输出
alert();
方式二:文档流输出
document.write();
方式三:控制台输出
console.log();
js的注释方式
//单行注释
/*
多行注释
*/
注释不会被浏览器解析,起到解释说明的作用,方便代码调试。
注意:注释内不要嵌套注释
1.4js的变量
变量是一个数据结构(可以改变的量),可以存放任何的数据类型
变量定义的方式:var 变量名;
var 是js的系统关键字(常见的系统关键字if else var continue break let const)
变量名的命名规范:
1、采用数字、字母、下划线以及$组成,但不能以数字开头
2、js中严格区分大小写
3、js中可以使用中文,但是不建议使用
4、不能使用系统关键字命名(if else var continue break)
注意:Unexpected token ‘break’
5、推荐驼峰命名法 firstName firstChild girlFriend firstElementChild name age time
注意:var声明的变量存在变量提升(声明提前,但是赋值并未提前)
<script>
console.log(apple);
var apple="iphone";
</script>
运行结果为:
变量提升:代码在执行的时候,会将"var apple"这句语句提升在console之前。
2.常见数据类型
方式一:一种数据类型(了解)
对象(object)js中到处都是对象,就算本身不是对象,在运算的过程中都会转换为对象
方式二:两种数据类型
1、值类型(undefined、string、number、boolean、null)
2、引用类型(object)
方式三:六种数据类型(重点)
未定义类型undefined
字符串类型String
布尔类型Boolean true false
数值类型Number(科学计数法、十六进制、无穷、除数、被除数、整型、浮点型)
空类型Null(object)
对象类型Object(object function)
对象的所属关系 instanceof,返回boolean值
检测数据类型typeof
方式一:typeof(被检测的变量)
方式二:typeof 被检测的变量
2.1undefined类型
什么情况下会出现undefined?
1、变量声明后未赋值,值为undefined
2、直接将变量的值赋值为undefined
3、函数的参数未传入实际的值,该参数未undefined
4、函数运行后,未给出返回值(return),则未undefined
5、对象的属性未进行定义,值也是undefined
<script>
// 1、变量声明后未赋值,值为undefined
var num;
console.log(num)
// 2、直接将变量的值赋值为undefined
var num=undefined;
console,log(num)
// 3、函数的参数未传入实际的值,该参数未undefined
function fun(a,b){
console.log(a,b)
}
fun(1)
// 4、函数运行后,未给出返回值(return),则未undefined
var res = fun(1,2)
console.log(res)//undefined
console.log(typeof res)//undefined
// 5、对象的属性未进行定义,值也是undefined
var obj = new Object();
console.log(obj.age)//undefined
</script>
2.2null类型
null空对象指针
null和undefined的区别
1、类型不同
Null为空对象指针,为object类型,undefined的类型为Undefined
2、undefined未定义类型,以后可以装任意的数据类型;而null为空对象指针,但以后接收对象类型
<script>
var nu = null;
console.log(typeof nu)//object
// ==(恒等)判断值是否相等,返回Boolean值
// === (全等) 判断值和类型是否相等,返回Boolean值
console.log(null == undefined);//true
console.log(null === undefined);//false
</script>
2.3string类型
在js中,采用引号定义字符串
注意:js中不区分单双引号,建议使用单引号。主要是为了和html中的双引号做区分。
注意:
1、 转义字符 ‘\’
2、js的连接符 '+'
var name = 'cdd';
var age = 18;
var newStr = name+'说:“我今年'+age+'岁”'
console.log(newStr)
// 转义字符
var str = "<p stylle=\"color:red\"></p>";
// var str = '<p stylle="color:red"></p>';
console.log(str)
2.4boolean类型
boolean主要用于后期做判断使用
主要分为两个值:true(真) false(假)
注意:当boolean进行计算的时候,true自动转化为1,false自动转换0
2.5number类型
(1)在js中不严格区分整型和浮点型,类型均为number
整型 (占4个字节) 取值范围为-2的53次方到2的53次方
浮点型(小数) (占8个字节)
注意:当整型超过取值范围,自动转换为浮点型
var num = 10.00100;
console.log(num)//10.001
console.log(typeof num)//number
(2)进制
二进制:逢二进一 0 1
八进制:逢八进一 0-7
十进制:逢十进一 0-9
十六进制:逢十六进一 0-9 a-f
10 a 11 b 12 c 13 d 14 e 15 f
数字采用0开头,首先考虑八进制,若后面数字超过7,则该数字为十进制
0x代表十六进制,在进制内不区分大小写
var num = 023;//19 0开头默认先考虑八进制 2*8+3*1=19
var num = 029;//29 后面的数字超过7,则为十进制 2*10+9*1=29
var num = 0xb;//11 十六进制
var num = 0xB;//11
console.log(num)
console.log(typeof num)//number
(3)科学计数法
e代表的是10的多少次方
例如 e3代表 101010 10的3次方
e-3代表 1/(101010) 10的3次方分之一
var num = 3.14e2;//314 e2代表10的2次方
var num = 3.14e-2;//0.0314 e-2代表10的-2次方
console.log(num)
console.log(typeof num)
(4)无穷Infinity
当除数为0的时候,会出现Infinity,但是程序不会终止,类型为number
var num = 0/10;//0 number
var num = 10/0;//Infinity(无穷) number
console.log(num)
console.log(typeof num)
(5)小数计算
单精度 双精度的影响
console.log(0.1+0.2);//永远不要相信js中小数的计算,更不能将其结果进行判断
console.log(0.2+0.1 == 0.3)//false
console.log(0.2+0.3 == 0.5)//true
console.log(1+2 == 3)//true
(6)NaN
NaN是如何产生的呢?(重点知道如何解决)
——通过运算希望得到一个数值类型,但是最终却没得到(比如价格的计算)
NaN是一个连自己都不认识自己的数值类型
只要NaN参与运算,其结果都为NaN
var num = 2 * '你好';//NaN
var num = 2 * '200px';//NaN
var num = 2 * '200';//400 纯数字的字符串在运算时将直接转换为数值
var num = 10 + '10';//1010 string + 此时作为连接符(当+两边为数值,则进行加法运算,若+两边有字符串,则作为拼接符)
console.log(num)
console.log(typeof num)
console.log(NaN == NaN)//false
console.log(NaN === NaN)//false
var num = NaN + 3;
var num = NaN - 3;
var num = NaN * 3;
var num = NaN / '3';
console.log(num)
2.6object类型
对象 object
(1)通过实例化生成对象new Object() 生成的对象叫做实例化对象
var obj = new Object();
//添加属性
obj.name = 'cdd';
//添加方法
obj.play = function(){
}
(2)通过字面量(json)去定义
var obj = {};
var person = {
name:'张三',
age:30,
say:function(){
console.log('三十而立')
}
}
对象的属性-----------------------变量
obj.属性名 = 属性值;
对象的方法----------------------函数
obj.方法名 = function(){
}
var name='cdd';
console.log(window.name)
//1,
var obj=new Object();
console.log(obj);
console.log(typeof obj)
//2,
var cat={
name:'tom',
gender:'boy',
hobby:function(){
console.log('eat!')
}
}
console.log(cat.name,cat.gender)
cat.hobby()
3.类型转换
隐式转换(自动转换)
强制转换
3.1隐式转换
注意:
1、纯数字的字符串在运算时,会自动转换为数值进行计算(除了+,’+'作为连接符使用)
2、布尔类型的值在运算时,true相当于1,false相当于0
3、只有空字符串(’’)会转换为false,只要有内容,则会转为true
4、数值类型除了0以外其余都转换为true(除了NaN),0将转换为false
tofixed(n)设置固定的小数位数 n代表小数点后保留几位
<script>
var res=5*'5';//25 number
var res=5+'5';//55 string
var res=2+true;//3 number
console.log(res)
console.log(typeof res)
</script>
3.2强制转换
强转为Boolean
var str=5;//true
var str=0;//false
var str='abc';//true
var str=' ';//true
var str='';//false
var str=undefined;//false
var str=null;//false
var res=Boolean(str)
console.log(res)
强转为字符串
String()
var res=String(num);
toString()建议使用
num.toString()
强转为数值类型(重点)
**parseInt()**强制转换为整型(重点)
解析进制(默认解析十六进制,不解析八进制)
小数转换为整型时,直接去除小数点后面的内容
解析字符串(解析第一个字母之前的数值,之前没有数值则为NaN)
扩展:
parseInt(string,radix) radix为基数,取值2-32
parseFloat()
不解析进制
解析字符串(解析第一个字母之前的数值,之前没有数值则为NaN)
解析小数,但只保留第一个小数点
Number()
解析进制(十六进制)
只解析纯数字的字符串(带字母不解析)
测试:
<script>
// parseInt()强制转换为整型
var num=9.1;//9 直接将小数位去除,不存在四舍五入
var num=9.9//9
var num='0xa';//10 可以识别进制
var num='023';//23 不识别八进制,默认为十进制
var num='123abc';//123 解析字符串 结果为第一个字母之前的值
var num='1a2b3c';//1
var num='abc123';//NaN
var num='3.14a';//3
var res=parseInt(num);
console.log(res);
// parseInt(string,radix) radix为基数,取值2-32
var str ='023';
var res=parseInt(str);//23 十进制
var res=parseInt(str,0);//不写参数,默认为0,代表为十进制
var res=parseInt(str,8);//19 八进制
var res=parseInt(str,16);//35 十六进制
console.log(res)
</script>
// parseFloat()强制转换为浮点型
var str='0xa'//0 不解析进制
var str='123abc';//123
var str='3.14a';//3.14
var str='3.14.115'//3.14
var res =parseFloat(str);
console.log(res);
//补充 toFixed(2)保留指定的小数位数
var num=36.00;
console.log(num)//36
var num=25;
var num=3.1415925;//3.14
var num=9.99999;//10.00
var res=num.toFixed(2);
console.log(res)
// Number()强制转换为数值
var str='0xa';//10
var str='123adc';//NaN
var str='123';//123
var res=Number(str);
console.log(res);
以上总结:
parseInt() | parseFloat | Number() | toFixed() | |
---|---|---|---|---|
解析进制 | 是,但不解析八进制 | 否 | 是,不解析八进制 | 否 |
解析字符串 | 是 | 是 | 是 | 否 |
解析数 | 是,向下取整 | 是 | 是 | 是 |
4.运算符
数学运算符 + - * / %(取余) ++ –
%计算的结果的余数
+ 注意作为连接符使用的情况
a++ 先将a的值参与运算,再将其加一
++a 先将a的值加一,再将加一后的结果参与运算
a-- 先将a的值参与运算,再将其减一
–a 先将a的值减一,再将减一后的结果参与运算
var a = 10;
var res = a++ + a++;//10+11
console.log(res)//21
var a = 10;
var res = ++a + a++;//11 + 11
console.log(res)
var a = 10;
var res = a++ + --a;//10+10
console.log(res)
赋值运算符 = += -= *= %=
比较运算符 > < >= <= != == (恒等) ===(全等)
三元运算符 (条件)? 成立时执行的代码 : 不成立时执行的代码
逻辑运算符
与 && 两者为真则为真,只要有假则为假
或 || 两者为假则为假,只要有真则为真
非 ! 真->假 假->真
逻辑运算符中存在逻辑短路
逻辑短路:当前面的条件可以直接判断出结果,则后面的条件将不会执行
注意:尽量把重要的先决条件放在前面
位运算符(了解)
位运算符:将值先转换为二进制,再按位计算
与 & 两者为真则为真,只要有假则为假
或 | 两者为假则为假,只要有真则为真
非 ~ 真->假 假->真
console.log(2&3)//2
console.log(2|3)//3
console.log(7&8)//0
console.log(7|8)//15
console.log(~5)//-6
console.log(~-6)//5
5->0101->补码:0101->补码+1:0110->给上符号位:-6;
-6->0110->补码:1001+1->1010->取反:0101->5
概念总结:
原码为正数,内存中的补码也为正数,按位取反后内存中的补码变为负数,当内存中的补码转化成原码时,原码等于=补码除符号位外逐位取反,并在最低位+1。
原码为负数,内存中的补码为原码的除符号位外逐位取反,并在最低位+1,按位取反后内存中的补码变为正数,当内存中的补码转化成原码时,原码=补码。
5.流程控制
条件判断
单向分支:如果符合条件则执行,不符合则跳过
if(条件){
}
双向分支
if(条件){
条件成立时执行
}else{
条件不成立时执行
}
多向分支
if(条件){
成立时执行
}else if(条件){
成立第二个条件时执行
}else{
条件均不成立时执行
}
switch…case
switch(条件){
case 分支:
break;
case 分支:
break;
//当所有的case都不满足时执行 一般放置在所有的case后面
default:
break;
}
循环
for循环(显示迭代)
for(初始值;判断条件;改变条件){
循环体
}
常见的例子:
for(var i=0;i<5;i++){
console.log(i)
}
循环中的关键字
break:终止整个for循环,后面的内容将不会执行
for(var i=1;i<10;i++){
// 如果满足条件则执行,不满足则跳过
if(i%2==0){
// 跳出整个循环体(跳出整个for循环,for循环的代码到此结束)
break;
}
console.log(i)//1
}
continue:结束当前循环,继续执行下一个循环
for(var i=1;i<10;i++){
// 如果满足条件则执行,不满足则跳过
if(i%2==0){
//跳出本次循环,继续执行下一个循环
continue;
}
console.log(i)//1 3 5 7 9
}
while循环
while(判断条件){
循环体
}
示例:
var i=0;
while(i<=10){
console.log(i);
i+=2;
}
do…while循环
do{
循环体
}while(判断条件)
var num = 5;
do{
console.log(num)
}while(num>10)
注意:
while是先判断再执行循环体内容
do…while是先执行一次循环体,再进行判断
6.函数
函数的概念:函数是一小块代码的封装,要求功能越独立越好,功能越强大越好。
6.1函数的定义
1、标准定义方式
function 函数名(参数){
函数体
}
function fun(){
console.log('标准函数定义')
}
注意:函数可以在任意的地方调用
2、赋值的方式
var 函数名 = function(参数){
函数体
}
fun()
var fun = function(){
console.log('通过赋值方式定义')
}
注意:赋值方式定义的函数只能在赋值之后才能调用
3、原生方法定义(了解,不建议使用)
var 函数名 = new Function(函数的具体内容);
var fun = new Function('console.log("原生方法定义")');
函数的调用:将函数体内的代码从上往下执行一遍
函数名(); 例如:fun() demo(实参)
6.2匿名函数
函数重名问题
当在一个js中,标准方式定义的函数名相同时,后面的函数会自动覆盖前面定义的函数,在任何地方都没法调用
注意:函数命名时,不能和系统函数重名
匿名函数
匿名函数:没有名字的函数
匿名函数的特点:
1、避免了函数取名的困扰
2、匿名函数永远不会被其他函数重写
3、匿名一般情况下,只调用一次。定义时则直接调用
// var fun = function(){
// console.log('匿名函数')
// }
// console.log(fun)
// fun()
// 匿名函数
(function(){
console.log('匿名函数')
})();
函数的参数(重点)
函数的参数
形参-----------形式参数(定义函数时小括号内的参数为形参)
实参-----------实际参数(调用函数时,小括内的参数为实参)
function 函数名(形参1,形参2...){
函数体...
}
函数名(实参1,实参2...);//函数调用
注意:形参和实参的个数不一定要相等
形参和实参的个数问题?
1、函数给出形参,但未传入实参
function fun1(a){
console.log(a)//undefined
}
fun1();
2、函数给出的形参个数大于实参个数
function fun2(a,b,c){
console.log(a,b,c)//1,2,undefined
}
// 实参按照从左往右的顺序分别给形参赋值
fun2(1,2)
3、函数给出的形参个数等于实参个数(常规情况)
function fun3(a,b){
console.log(a,b)//10 20
}
fun3(10,20);
4、函数给出的形参个数小于实参个数
function fun4(a){
console.log(a)//1
}
fun4(1,2,3)//a=1 2 3则没有参数来接收
5、函数给出实参,但未给出形参
function fun5(){
// 可以通过arguments接收所有的参数,采用数组的方式返回
console.log(arguments)//["胡桃", "甘雨", "魈"]
// 数组的下标默认从0开始,可通过指定下标获取对应的值
console.log(arguments[2])//魈
}
fun5('胡桃','甘雨','魈')
注意:系统有一个arguments可以接收所有的实参
6.3函数的返回值return
注意:console.log()只是输出,函数的返回值只和return有关
函数的返回值的几种情况
1、函数调用后未给出return返回值,则调用后的结果为undefined
function fun1(){
console.log('测试代码:不给返回值')
// 此时函数调用后仍然为undefined.因为没有返回具体的值
return
}
// 将函数调用的结果赋值给一个变量,该变量就就接收函数return的返回值
// 如果没有return,则返回undefined
var res = fun1()
console.log(res)//undefined
2、函数调用后通过return返回值(可以为任意数据类型,变量,表达式)(重点)
函数调用的结果则为函数返回值(return后面的内容)
// return 返回字符串 数字 boolean 变量 表达式
function fun2(){
var name = '张羿'
return name+'会射太阳吗';
}
var res = fun2()
console.log(res)
// return 返回对象
function fun3(){
// var obj = {
// name:'张三',
// sex:'男'
// }
return {name:'张三',sex:'男'};
}
var res = fun3()
console.log(res)
// return 返回函数
function fun4(){
// var fun = function(){
// console.log('张三丰')
// }
function fun(){
console.log('张三丰')
}
return fun;
}
var res = fun4()
console.log(res)
res()
3、return后面的代码不执行
function fun3(){
console.log('我不想看到你')
return 111;
// return后面的代码不会被执行
console.log('看看我在不在')
}
var res = fun3();
console.log(res)
4、函数调用后可以给出返回值,也可以不给(return不是必须的)
6.4函数的变量
**作用域:**变量的作用范围(使用的范围的大小)
全局变量:
定义:在函数体的外部定义的变量(推荐),或者在函数体内部不采用var声明的变量(但是不推荐此写法)
作用域:作用范围广,可以在任意地方均可以访问和修改,故叫做全局变量。只有整个js文件运行结束后,全局变量才销毁。
注意:一旦全局变量被更改,所有使用的地方都会被影响。所以合理使用(全局变量污染)。
局部变量:
定义:在函数体的内部采用var定义的变量
作用域:作用范围只在函数体的内部,作用范围小,故叫做局部变量。函数执行完成后,局部变量则被销毁
注意:
建议能使用局部变量则尽量使用局部变量
不同的函数之间,局部变量名可以重复使用
当全局变量和局部变量发生冲突时,优先使用局部变量
函数的作用域链
函数的作用域链:变量是(从内往外)一级一级的向上查找(父级函数),直到找到为止,反之不成立
函数查找变量的方式:
1、先查找当前函数是否具有该变量,则使用该变量
2、若当前函数没有,则向父级函数查找是否有该变量,若有,则使用改变量
3、若直到找到最大的作用域,没发现该变量,则系统认为该该变量不存在
6.5回调函数
回调函数(重点)
定义:形参中至少有一个是已定义好的函数
回调的意义:我们可以在函数的内部调用其他函数(且函数名还可以切换)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
function add(a,b){
if((a>0&&a<1)||(b>0&&b<a)){
//拆分小数点后的数字
var l1=a.toString().split(".")
var l2=b.toString().split(".")
var lenth=Math.max(l1[1].length,l2[1].length)
return ( a*Math.pow(10,lenth)+b*Math.pow(10,lenth))/Math.pow(10,lenth)
}
else
return a+b;
}
function minus(a,b){
return a-b;
}
function multiply(a,b){
return a*b;
}
function divde(a,b){
if(b==0){
console.log('除数不能为0!')
}
else
return a/b;
}
function calculator(a,b,method){
return method(a,b);
}
var res=calculator(0.1,0.2,add)
console.log(res)
</script>
</body>
</html>
6.6闭包函数(重点)
(重点:注意笔试面试考闭包的概念)
闭包函数:内部函数在其作用域外被调用,则形成了内部函数的闭包
若闭包函数使用了全局变量,则该变量所占的内存不会被释放。直到整个js运行结束。
闭包函数的特点:
优点:内部的函数可以在其作用域之外被访问
缺点:占内存,可能存在内存泄漏,慎用闭包。除非必须使用某个局部变量
解决方案:在内部函数调用完成之后,将该内存释放。(将该变量赋值为空)
function outside(){
// function inside(){
// console.log('sss')
// }
//系统会认为已存在num变量,后面几次调用不会重新覆盖
var num = 100;
var inside = function(){
num++;
console.log(num)
}
// 将整个函数作为返回值返回
return inside;
}
var res = outside()
console.log(res)//此时的res 接收的是Outside返回的函数
// 调用返回的函数
//普通调用方式,该方式会造成内存占用,可能存在内存泄漏
res()//101
outside()
res();//102
outside()
res();//103
//该调用方式,在调用结束后手动释放内存
var res = outside()
res()//101
// 将返回值返回的函数进行清空,释放内存空间
res = null;
6.7递归
定义:自己调用自己
function fun(n){
console.log(n)//3 2 1 0
if(n>0){
fun(n-1)//fun(2) fun(1) fun(0)
}
}//3 2 1 0
function fun(n){
console.log(n)//3 2 1 0
// 在递归函数中,若在自己调用自己后还有代码,则该代码需要等到不满足条件时,依次返回执行
if(n>0){
fun(n-1)//fun(2) fun(1) fun(0)
}
console.log(n)
}
fun(3)//3 2 1 0 0 1 2 3
递归理解:
function fun(2){
console.log(2)
if(2>0){
// fun(1)
console.log(1)
if(1>0){
// fun(0)
console.log(0)
if(0>0){
//跳过 不符合
}
console.log(0)
}
console.log(1)
}
console.log(2)
}
递归实现阶乘
方法一:
var num = 1;
function fun(n){
if(n>1){
num*=n;//num = num*n; 1*3*2*1
fun(n-1)//fun(2) fun(1)
}else{
return 1;
}
// 将阶乘的结果进行返回
return num;
}
var res = fun(3);//1*2*3*4...*10
console.log(res)
方法二:
function fun(n){
if(n==0 || n==1){
return 1
}
else if(n>1){
return n* fun(n-1)
}
else{
return '你输入的数的格式不合理'
}
}
let res=fun(10)
console.log(res)
7.对象
7.1认识对象
创建对象
var obj = new Object();
查看对象原型
console.log(obj.__proto__);
// 通过原生方法Object查看对象原型
console.log(Object.prototype)
注意:constructor为对象的构造函数
在对象原型下添加方法
// 在对象原型下定义方法
Object.prototype.play = function(){
console.log('张家界去不得');
}
原型链:从当前实例化对象开始一级一级向上查找原型,最顶层对象原型为Object.prototype,而Object.prototype的原型为null,没有任何属性和方法
instanceof
instanceof
查看对象原型所属关系,返回一个boolean值
<script type="text/javascript">
var arr =new Array()
console.log(typeof arr)//object
var str =new String()
console.log(typeof str)//object
console.log(arr instanceof Array)//true
console.log(arr instanceof String)//false
console.log(str instanceof String)//true
console.log(str instanceof Array)//false
console.log(str instanceof Object)//true
console.log(arr instanceof Object)//true
</script>
7.2数组
数组定义
方式一:
var arr = new Array();
// 若只有一个数字作为参数:该数字为创建数组的长度
var arr = new Array(5);
console.log(arr)//empty*5
//该参数不是数字,则代表数组内实际的值
var arr = new Array('cdd');
console.log(arr)//["cdd"]
// 若参数超过一个,则代表数组具体的值
var arr = new Array(1,2,3);
console.log(arr)//[1, 2, 3]
方式二:
var arr=[]
length为数组的长度
数组的下标为数字,默认从0开始递增
数组最大的下标+1=数组的长度
7.3数组的CRUD
访问数组内的值(通过其下标访问)
arr[i] i代表指定的下标
添加指定下标的值
arr[]={'胡桃','甘雨'}
arr[2]='魈'
console.log(arr)//['胡桃','甘雨','魈']
修改指定下标的值
arr[]={'胡桃','甘雨'}
arr[0]='魈'
console.log(arr)//['魈','甘雨']
删除指定下标的值 delete() splice()
注意:
1,delete只是将对应下标的值进行删除,保留键
2,splice(start,num)删除 ,该删除不保留键
- start 删除的起始下标
- num 删除的个数
arr[]={'胡桃','甘雨'}
delete(arr[0])
console.log(arr)//[empty,'甘雨']
arr.splice(0,1)
console.log(arr)//['甘雨']
7.4数组遍历
显示迭代:
for(var i=0;i<arr.length;i++){
console.log(arr[i])
}
隐式迭代
arr.forEach(function(val,key,ownObj){
//第一个参数为数组的值
//第二个参数为数组的下标
//第三个参数为当前遍历的数组
})
对象的遍历(重点)
for...in...
语法:for(var 变量名 in 遍历的对象){
}
注意:该变量名则为对象的属性名和方法名(键)
for(var key in obj){
console.log(key)//key为当前对象的属性名和方法名
console.log(obj[key])//obj[key]可以取出对应的属性值和方法
练习:去除数组中的undefined,null
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<!-- 方法一: -->
<script type="text/javascript">
let arr=[1,2,3,undefined,undefined,6,undefined,9,undefined,null]
function clear(arr){
let list=[];
for(let i=0;i<arr.length;i++){
if(typeof arr[i] == 'number'){
list.push(arr[i])
}
}
return list
}
let res=clear(arr)
console.log(res)
</script>
<!-- 方法二: -->
<script type="text/javascript">
let arr1=[1,2,3,undefined,undefined,6,undefined,9,undefined,null]
function clear(arr){
//先排序
arr.sort()
let n=0;
for(let i=0;i<arr.length;i++){
if(typeof arr[i] !=typeof arr[i+1]){
n=i+1
break;
}
}
arr.splice(n,arr.length)
return arr
}
let res1=clear(arr1)
console.log(res1)
</script>
<script type="text/javascript">
let arr3=[1,2,3,undefined,undefined,6,undefined,9,undefined,null]
function clear(arr){
let list2=[];
arr.forEach(function(value,i){
if(typeof arr[i] == 'number'){
list2.push(arr[i])
}
})
// for(let i=0;i<arr.length;i++){
// if(typeof arr[i] == 'number'){
// list.push(arr[i])
// }
// }
return list2
}
let res3=clear(arr3)
console.log(res3)
</script>
</body>
</html>
7.5数组函数
函数三要素:功能、参数、返回值
cancat()
***concat()**连接两个或更多的数组,并返回结果
var a=['胡桃','甘雨','魈']
var b=['琴','芭芭拉','迪卢克']
var c=['万叶','神里']
// 拼接
var arr=a.concat(b)
console.log(arr)
var arr =a.concat(c,b,'埃洛伊')
console.log(arr)
join()
***join(指定的字符)**将数组按照指定的字符拼接成字符串(将数组转换为字符串)
注意:join默认按照’,'进行拼接
//join() 将数组转换为字符串,split() 将字符串转为数组
var arr =['埃','洛','伊','将','被','免','费','赠','送']
var str=arr.join()//埃,洛,伊,将,被,免,费,赠,送
var str=arr.join('')//埃洛伊将被免费赠送
console.log(str)
数组入栈、出栈
***push()**向数组的末尾添加一个或更多元素,并返回新的长度(多个元素采用逗号连接)
***pop()**删除并返回数组的最后一个元素(不需要传参)
***unshift()**向数组的开头添加一个或更多元素,并返回新的长度.(多个元素采用逗号连接)
***shift()**删除并返回数组的第一个元素(不需要传参)
/*
函数直接改变原数组
push()从数组的尾部压入一个元素
pop()从数组的尾部弹出一个元素,将弹出的元素进行返回
unshift()从数组的头部压入一个元素
shift()从数组的头部弹出一个元素,并将弹出的元素进行返回
*/
var arr =['胡桃','甘雨','魈','芭芭拉','菲谢尔']
arr.push('优菈')
arr.pop()
arr.unshift('空')
arr.shift()
console.log(arr)
slice()
***slice(start,end)**数组的截取
slice(start)(第一个参数必填)从指定下标(start)开始截取,截取到最后
slice(start,end)从指定下标(start)开始截取,截取到指定结束下标(end)之前
注意:
1、在截取数组时,包含起始下标(start),不包括结束下标(end)
2、截取的下标可以为负数,代表倒数第几个
3、slice截取为从左往右截取
var arr=[1,2,3,4,5]
console.log(arr)
console.log(arr.slice(1))//[2, 3, 4, 5]
console.log(arr.slice(-1))//[5]
console.log(arr.slice(1,4))//[2, 3, 4]
console.log(arr.slice(-3,4))//[ 3, 4]
console.log(arr.slice(-4,-1))//[2, 3, 4]
splice()
***splice(index,num,item)**删除、修改或者添加数组的元素 (改变原数组)
index:代表从指定的索引(下标)开始
num:删除的个数
splice(index,num)从指定的下标(index)开始,删除num个
splice(index,num,item)从指定的下标(index)开始,将指定的num个的内容替换为item
注意:splice和delete删除不同点:
splice删除数组的值,不保留键
delete删除数组的值,保留键(此时对应的下标的值为undefined)
splice可以接收返回值,返回值为数组,返回被删除的内容
//del
var arr =['胡桃','甘雨','魈','芭芭拉','菲谢尔']
arr.splice(1,2)
console.log(arr);// ["胡桃", "芭芭拉", "菲谢尔"]
var arr =['胡桃','甘雨','魈','芭芭拉','菲谢尔']
arr.splice(0,2)
console.log(arr);// ["魈", "芭芭拉", "菲谢尔"]
//update
var arr =['胡桃','甘雨','魈','芭芭拉','菲谢尔']
arr.splice(1,1,'莫娜')
console.log(arr);// ["胡桃", "莫娜", "魈", "芭芭拉", "菲谢尔"]
//add
var arr =['胡桃','甘雨','魈','芭芭拉','菲谢尔']
arr.splice(1,0,'莫娜')
console.log(arr);// ["胡桃", "莫娜", "甘雨", "魈", "芭芭拉", "菲谢尔"]
reverse()
**reverse()**反转,颠倒数组元素的排序
//数组反转
let arr=[1,2,3,4]
console.log(arr.reverse())// [4, 3, 2, 1]
sort()
**sort()**对数组的元素进行排序(按照ASCII的码值进行排序)
sort(sortby)了解
sortby必须为一个函数
//sort()
let arr2=[12,1,2,45,22,11,0]
//自定义规则排序
//升序
function esc(a,b){
if(a>b){
return 1;
}else if(a==b){
return 0;
}else if(a<b){
return -1;
}
}
console.log(arr2.sort(esc))//[0, 1, 2, 11, 12, 22, 45]
//降序
let arr3=[12,1,2,45,22,11,0]
function desc(a,b){
if(a>b){
return -1;
}else if(a==b){
return 0;
}else if(a<b){
return 1;
}
}
console.log(arr3.sort(desc))//[45, 22, 12, 11, 2, 1, 0]
indexOf()
***indexOf()**查找指定元素在数组中第一次出现的位置
如果该元素存在数组中,则返回该元素的下标,若不存在则返回-1
***lastIndexOf()**查找指定元素在数组中最后一次出现的位置
var arr=['胡桃','甘雨','莫娜','七七','莫娜']
console.log(arr.indexOf('七七'))//3
console.log(arr.lastIndexOf('莫娜'))//4
console.log(arr.indexOf('凝光'))//-1
拓展ASCLL
注意:默认按照ASCII的码值从小到大排序
资料:ASCII的介绍 http://ascii.911cha.com/
拓展:0-9 编码为48-57 A-Z 编码为65-90 a-z 编码为97-122
ES6的数组函数:
map
filter
7.6字符串函数
length
字符串中的length属性
语法:str.length
字符串的查找
字符串查找指定下标的值(es6中使用)
str[index] index为指定的下标
字符串的查找
**charAt(index)**获取指定下标对应的值(index为下标,默认从0开始)
注意:若index的值超过0到字符串的长度,则返回的值为空字符串
**charCodeAt(index)**返回在指定的位置的字符的 Unicode 编码(ASCII码值)
**fromCharCode(num)**可接受一个指定的 Unicode 值,然后返回一个字符串
语法: String.fromCharCode(num) num为unicode编码
(indexOf lastIndexOf重点内容)
***indexOf()**查找指定字符第一次出现的位置
***lastIndexOf()**查找指定字符最后一次出现的位置
var str='什么?稻妻的雷神竟然有两个?'
console.log(str)
console.log(str[0])//什
console.log(str.charAt(0))//什
console.log(str.charCodeAt(0))//20160
console.log(String.fromCharCode(20160))//什
console.log(str.indexOf('?'))//2
console.log(str.lastIndexOf('?'))//13
console.log(str.indexOf('*'))//-1
字符串大小写转换
**toLowerCase()**将字符串转换为小写字母
**toUpperCase()**将字符串转换为大写字母
var a='abc'
var b='edfg'
console.log(a.toUpperCase())//ABC
console.log(a.toUpperCase().toLocaleLowerCase())//abc
字符串的拼接
***concat()**用于连接两个或多个字符串
var a='abc'
var b='edfg'
console.log(a.concat(b))//abcedfg
console.log(a.concat(b,'hao'))//abcedfghao
字符串的截取
***split()**将字符串按照指定的字符分割为数组(字符串转换为数组)
***slice(start,end)**截取指定下标的字符串
slice(start)(第一个参数必填)从指定下标(start)开始截取,截取到最后
slice(start,end)从指定下标(start)开始截取,截取到指定结束下标(end)之前
注意:
1、在截取字符串时,包含起始下标(start),不包括结束下标(end)
2、截取的下标可以为负数,代表倒数第几个
3、slice截取为从左往右截取
***substr(start,num)**从起始索引(下标start)提取字符串中指定数目(num)的字符
start:起始下标(索引)
下标可以为负数,代表从倒数第几个开始
num:截取的字符串个数(截取的个数不能为负数)
**substring(start,stop)**提取字符串中两个指定的索引号之间的字符
注意:substring()功能基本和slice()一致,只是两个下标可以随意放置
ES6中的字符串函数使用
***trim()**去除字符串两侧的空格
var str='什么?稻妻的雷神竟然有两个?'
console.log(str.split())//["什么?稻妻的雷神竟然有两个?"]
console.log(str.split(''))//["什", "么", "?", "稻", "妻", "的", "雷", "神", "竟", "然", "有", "两", "个", "?"]
console.log(str.slice(0,3))//什么?
console.log(str.substr(2,3))//?稻妻
var str='什么?稻妻的雷神竟然有两个?'
//substring(start,stop)提取字符串中两个指定的索引号之间的字符
console.log(str.substring(0,2))//什么
// trim()去除字符串两侧的空格
var str=" 没错,很有 可能 "
console.log(str.trim())//没错,很有 可能
正则中的字符串查找匹配(正则表达式一起讲解)
search()
match()
replace()
7.7数学函数
数学函数的方法
abs()绝对值
max()最大值 注意:参数不能直接接收数组
min()最小值
*floor()向下取整(舍去所有的小数位)
ceil()向上取整(进一法取整)
round()四舍五入
*random()随机数
注意:默认产生0-1的随机数(可以取到0,但取不到1)
pow(x,y)次方根 返回x的y次幂
sqrt()开平方根
数学函数的属性
E 算数常量 代表e
PI 返回圆周率
//绝对值
console.log(Math.abs(-1))//1
//最大值
console.log(Math.max(1,5,2,3))//5
//最小值
console.log(Math.max(1,5,2,3))//5
// Math.max() Math.min()不能直接接收数组作为参数
var arr = [1,2,4,6,20,26];
var res = Math.max(arr)
console.log(res)//NaN
//apply()切换对象
var res=Math.max.apply(Math,arr)
console.log(res)//26
//向下取整floor()
console.log(Math.floor(9.9))//9
//向上取整ceil()
console.log(Math.ceil(9.1))//10
//四舍五入
console.log(Math.round(9.1))//9
console.log(Math.round(9.5))//10
// pow()次方根
console.log(Math.pow(2,5))//32
// sqrt()开平方根
console.log(Math.sqrt(9))//3
// 随机数random()生成0-1的随机数,不能取到1,可以取值为0
var num = Math.random();
console.log(num)
// 取值为0-9的随机数
var num = Math.floor(Math.random()*10)
console.log(num)
// 随机生成0-255的数
var num = Math.floor(Math.random()*256)
console.log(num)
var arr = ['胡桃','行秋','七七','甘雨','魈','钟离','温蒂'];
var index = Math.floor(Math.random()*arr.length)
console.log(arr[index])
7.8时间函数
var date = new Date();
console.log(date)
// 查看对象原型内的方法
console.log(date.__proto__)
三种时间表现方式:
1、标准时间 toString()
2、国际时间 toLocaleString()
3、时间戳 valueOf()
在js中时间戳为14个数字(单位:毫秒)
时间戳返回的是当前时间距离1900年1月1日(时间纪元)零时的毫秒数
var date = new Date();
console.log(date.getFullYear())//2021
console.log(date.getDate())//30
console.log(date.getYear())//121
console.log(date.toString())//Fri Jul 30 2021 20:57:16 GMT+0800 (中国标准时间)
console.log(date.toLocaleString())//2021/7/30下午8:57:41
console.log(date.valueOf())//1627649898728
GMT:格林威治时间(格林尼治或者天文学时间)
UTC:通用协调时
北京位于东八区 北京时间=UTC+8小时时差
7.9定时器
设置定时器
setTimeout(callback,时间)一次性定时器(只执行一次则结束)
callback代表回调函数 时间单位:毫秒
过多久时间执行一次函数体的内容
setTimeout(function(){
函数体
},1000)
setInterval(callback,时间)循环定时器(一直循环执行)
setInterval(function(){
函数体
},1000)
注意(方便理解):
for和setInterval的区别:
1、for在不满足判断条件会停止,setInterval若不进行手动清除,则不会停止
2、for不能控制每一次循环的时间,setInterval可以去控制每一次循环的时间
清除定时器
clearTimeout()清除一次性定时器
clearInterval()清除循环定时器
setTimeout(function(){
console.log(111)
},1000)
var time;
function start(){
time=setInterval(function(){
console.log(111)
},100)
}
function stop(){
clearInterval(time)
}
8.BOM
window对象
screen屏幕对象
location对象
history历史记录
navigator浏览器信息
window对象
在ES5中,最大的对象叫做Window,在ES6中,最大的对象为global
window的属性
screenLeft(screenX)获取浏览器左上角距离屏幕的X坐标
screenTop(screenY)获取浏览器左上角距离屏幕的Y坐标
innerWidth返回窗口的文档显示区的宽度(不包括任务栏和滚动条)
innerHeight返回窗口的文档显示区的高度
outerWidth返回窗口的宽度(包括任务栏和滚动条)
outerHeight返回窗口的高度
拓展:
offsetWidth获取指定对象的宽度
offsetHeight获取指定对象的高度
offsetLeft获取指定对象距离左侧的位置
offsetTop获取指定对象距离顶部的位置
scrollTop
opener返回对子窗口创建的引用(使用IE测试)
close返回窗口是否已关闭,返回Boolean 已关闭->true 未关闭->false
window的几种弹框方式
方式一:警告框
alert() 中断代码执行
方式二:显示带有一段消息以及确认按钮和取消按钮的对话框
confirm() 返回boolean值 确定->true 取消->false
方式三:输入弹框
prompt() 将输入框内输入的内容作为返回值返回
window的方法
open()打开一个新窗口或者已存在的窗口,返回一个window对象
moveTo()将窗口移动到指定的坐标
moveBy()将窗口按照指定的像素移动位置
resizeTo()将窗口大小调整到指定的宽度和高度
resizeBy()按照指定的宽度和高度调整窗口大小
scrollTo()将滚动条滚动到指定的像素
scrollBy()将滚动条按照指定的像素调整
close()关闭浏览器窗口
事件(重点)
onload监听页面加载
onunload监听页面退出(刷新 关闭页面)
onscroll监听页面滚动条滚动
location对象
host设置或返回主机名和端口号
hostname设置或返回主机名
port设置或返回端口号
protocol返回协议 比如:http https ftp
http状态码:https://www.runoob.com/http/http-status-codes.html
200 OK 请求成功
301永久移动
302临时移动
304 重定向 Not Modified
403服务器理解请求客户端的请求,但是拒绝执行此请求
404 not found 页面找不到
500 服务器错误
*href设置或返回完整的 URL (跳转会有历史记录)
pathname设置或返回URL的路径部分
拓展知识:
网址(域名) localhost http://www.jd.com:8080
公网ip地址 127.0.0.1
https和http的主要区别
HTTPS和HTTP的区别主要如下:
1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全
location的方法
assign()加载新文档
replace()加载新文档覆盖当前文档 无历史记录
reload()重新加载文档 F5 reload(true) ==ctrl+ F5 强制刷新
assign()和replace()的区别:
assign()加载文档会有历史记录
replace()加载没有历史记录
history对象
length返回浏览器历史列表中url的数量
forward()加载 history 列表中的后一个 URL
back()加载 history 列表中的前一个 URL
*go(n)加载 history 列表中的某个具体页面 n为数字,代表回到哪一个历史记录
注意:
go(-1)和back()效果一致
go(1)和forward()效果一致
9.DOM
DOM (document object model)文档对象模型,属于window,是window的子对象
9.1DOM简介
W3C的标准,规定了如何通过Js创建web模型,可以通过js去操作页面的标签和样式,DOM既不属于html,也不属于javascript,是各大浏览器厂商指定一个页面执行标准
在HTML DOM标准中,所有的内容都是一个节点,所有节点的组合,我们叫做节点树
每一个标签是一个元素节点
每一个属性是一个属性节点
每一个文本是文本节点
每一个注释都是节点
整个html的document是一个文档节点
9.2常用结点
结点类型 | 节点标号 | 结点名 | 结点值 |
---|---|---|---|
元素结点 | 1 | 标签名(大写) | null |
属性结点 | 2 | 属性名 | 属性值 |
文本结点 | 3 | #text | 文本类型 |
文档结点 | 9 | #document | null |
结点特性:
nodeType:节点类型
nodeName:节点名
nodeValue:节点值
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h3 style="color: lightblue;" id="box">异世相遇,尽享美味</h3>
<script type="text/javascript">
//元素结点
var res=document.getElementById('box');
console.log(res.nodeType)//1
console.log(res.nodeName)//H3
console.log(res.nodeValue)//null
// 属性结点
var res=document.getElementById('box');
console.log(box.attributes)//NamedNodeMap {0: style, 1: id, style: style, id: id, length: 2}
var id=box.attributes[0];
console.log(id.nodeType)//2
console.log(id.nodeName)//style
console.log(id.nodeValue)//color: lightblue;
//文本节点
var res=document.getElementById('box');
var text=box.firstChild;
console.log(text.nodeType)//3
console.log(text.nodeName)//#text
console.log(text.nodeValue)//异世相遇,尽享美味
//文档结点
console.log(document.nodeType);//9
console.log(document.nodeName);//#document
console.log(document.nodeValue);//null
</script>
</body>
</html>
9.3结点访问
检测结点
childNodes 获取所有的子节点(以数组的方式返回)
**hasChildNodes()**检测是否具有子节点(返回boolean值 true->具有子节点 false->没有子节点)
获取结点
firstChild查找第一个子节点
lastChild查找最后一个子节点
nextSibling查找下一个兄弟节点
previousSibling查找上一个兄弟节点
parentNode父节点
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<ul id="box">
<li>望风山地</li>
<li>踏鞴砂</li>
<li>离岛</li>
<li>轻策庄</li>
</ul>
<script type="text/javascript">
/**
* firstChild查找第一个子节点
lastChild查找最后一个子节点
nextSibling查找下一个兄弟节点
previousSibling查找上一个兄弟节点
parentNode父节点
*/
var box =document.getElementById('box')
//childNodes返回元素中所有子节点
console.log(box.childNodes)//其他游览器这个方法会将空格也算入结点中 ,ie低版本不会算入
//nextSibling查找下一个兄弟结点
console.log(box.firstChild.nextSibling)
//兼容性解决方法
console.log(box.firstChild)//#text
console.log(box.firstChild.nodeType)//3
box.firstChild.nodeType == 3?box.firstChild.nextSibling:box.firstChild;
//获取第一个子节点
console.log(box.firstChild)//#text
//获取最后一个子节点
console.log(box.lastChild)//#text
console.log(box.lastChild.previousSibling)
//兼容性
box.lastChild.nodeType==3?box.lastChild.previousSibling:box.lastElementChild
//获取父节点
console.log(box.parentNode)//body
console.log(box.parentNode.parentNode)//html
console.log(box.parentNode.parentNode.parentNode)//#document
</script>
</body>
</html>
新的获取方式
新的获取方式:(高版本浏览器支持)
firstElementChild查找第一个元素子节点
lastElementChild查找最后一个元素子节点
nextElementSibling查找下一个元素节点
previousElementSibling查找上一个元素节点
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<ul id="box">
<li>望风山地</li>
<li>踏鞴砂</li>
<li>离岛</li>
<li>轻策庄</li>
</ul>
<script type="text/javascript">
/**
* 获取元素(只支持新版游览器)
* firstElementChild查找第一个元素子节点
lastElementChild查找最后一个元素子节点
nextElementSibling查找下一个元素节点
previousElementSibling查找上一个元素节点
*/
//var box=document.getElementById('box')
var box=document.querySelector('#box')
console.log(box.firstElementChild)//相当于如下
console.log(box.firstChild.nextSibling)
console.log(box.lastElementChild)//相当于如下
console.log(box.lastChild.previousSibling)
var oLi=document.querySelector('li')
console.log(oLi)//默认只拿到了第一个
var oLi=document.querySelectorAll('li')
console.log(oLi)//显示全部查到的元素
</script>
</body>
</html>
克隆
克隆节点(复制)
**cloneNode()**克隆节点
**cloneNode()**只克隆标签和属性
**cloneNode(true)**克隆标签+属性+文本
注意:若克隆的元素存在id属性,先修改其id的属性值,再添加到文档中
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div>
<p id="text">随便花</p>
</div>
<script type="text/javascript">
//克隆,只克隆标签
var text=document.getElementById('text')
var res=text.cloneNode()
console.log(res)//文字内容没有了
//如果想想获取标签内的内容
var res=text.cloneNode(true)
console.log(res)
//克隆一个标签显示出来
var p=document.getElementsByTagName('p')[0]
p.appendChild(res)
/**
* 注意:cloneNode(true)克隆标签+属性+内容
*/
</script>
</body>
</html>
9.4元素结点
创建,添加,移除,替换
创建元素:
createElement(标签名)创建元素节点
添加元素:
appendChild(元素节点)向指定节点追加一个子节点(默认放到所有子节点的末尾)
insertBefore(添加的元素,添加到指定元素之前)将元素添加到指定的节点之前
替换元素(修改元素)
replaceChild(替换后元素,替换前元素)替换元素节点
移除元素
removeChild(移除的元素)移除指定的子元素
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<ul id="box">
<li>111111111</li>
<li>111111111</li>
<li>111111111</li>
<li>111111111</li>
</ul>
<script type="text/javascript">
//createElement创建元素结点
var h2=document.createElement('h2')
h2.innerHTML='异世相遇'
console.log(h2)
var box=document.getElementById('box')
//appendChild
box.appendChild(h2)
</script>
</body>
</html>
//createElement创建元素结点
var h2=document.createElement('h2')
h2.innerHTML='异世相遇'
console.log(h2)
var box=document.getElementById('box')
//appendChild ,默认添加最后
box.appendChild(h2)
var oLi=document.getElementsByTagName('li');
//insertBefore添加元素到指定元素之前,同一个标签只能设置一次添加
box.insertBefore(h2,oLi[1])
//replaceChild替换标签
var input=document.createElement('input')
box.replaceChild(input,oLi[2])
//移除子元素
box.removeChild(oLi[0])
元素节点获取
元素节点获取
获取单个元素:(直接返回元素节点)
getElementById()通过id名获取元素
querySelector()通过css选择符获取(必须高版本浏览器)
获取多个元素:(以数组的方式返回)
getElementsByClassName()通过class类名获取元素
getElementsByTagName()通过标签名获取元素
getElementsByName()通过name的值获取元素
querySelectorAll()通过css选择符获取所有
案例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
#box{
width: 800px;
height: 400px;
background-color: aquamarine;
margin: 50px auto;
}
ul{
display: flex;
list-style: none;
font-size: 20px;
}
ul li{
width: 160px;
height: 50px;
text-align: center;
line-height: 50px;
background-color: lightseagreen;
border-bottom: 6px solid transparent;
}
ul li.active{
border-bottom: 6px solid red;
}
</style>
</head>
<body>
<div id="box">
<ul>
<li class="active">可莉</li>
<li>甘雨</li>
<li>胡桃</li>
<li>七七</li>
<li>优菈</li>
</ul>
</div>
<script type="text/javascript">
var arr =document.querySelectorAll('li');
for(var i=0;i<arr.length;i++){
arr[i].onclick=function(){
for(var j=0;j<arr.length;j++){
// arr[j].removeAttribute('class')
arr[j].style.borderBottom='6px solid transparent'//不推荐使用
}
//this.setAttribute('class','active')
this.style.borderBottom='6px solid red'//不推荐使用
}
}
</script>
</body>
</html>
9.5属性结点
attributes查看所有的属性节点 返回的值和数组类似,但不是真正的数组,他是所有属性的集合对象
获取指定的某个属性节点
- obj.attributes[i]
- obj.attributes.item(i)
重点:
**getAttribute(key)**获取指定属性结点的值 text
**setAttribute(key,val)**添加或修改指定属性节点
当属性名不存在时,则为添加属性节点
当属性名已存在时,则为修改属性节点
**removeAttribute(key)**移除指定的属性节点
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h2 style="color:red;"id="one">逃跑的太阳</h2>
<script type="text/javascript">
var one =document.getElementById('one');
console.log(one)
//attributes以数组方式返回所有的属性结点
console.log(one.attributes)
//NamedNodeMap {0: style, 1: id, style: style, id: id, length: 2}
//通过下标获取到属性结点
console.log(one.attributes[0])//style="color:red"
console.log(one.attributes.item(0))//style="color:red"
/**
* getAtrribute(key)获取属性结点的值
* getAtrribute(key,value)设置或者修改属性结点
* removeAtrribute(key)移除属性结点
*/
console.log(one.getAttribute('id'))//one
//属性名不存在的时候则添加属性名
one.setAttribute('name','可莉')
one.setAttribute('class','text1')
//移除属性
one.removeAttribute('style')
</script>
</body>
</html>
了解 :
createAttribute()创建属性节点
getNamedItem(key)获取指定的属性节点 id="text"
setNamedItem(attr)设置属性节点 (注意:设置之前必须先创建属性节点)
removeNamedItem(key)移除指定的属性节点
9.6文本结点
*innerHTML设置或获取位于对象起始和结束标签内的HTML (标签+文本)
outerHTML设置或获取对象及其内容的HTML形式(本身对象标签+标签+文本)
*innerText获取或者设置对象内的文本
outerText获取或者设置对象内的文本
*textContent获取或者设置对象内的文本
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<p>异世相遇,尽享美味</p>
<div>
<a href="#">风龙废墟</a>
</div>
<script type="text/javascript">
var p=document.querySelector('p');
console.log(p)
var div=document.querySelector('div')
//innerHtml,获取的是文本+标签
console.log(p.innerHTML)//异世相遇,尽享美味
console.log(div.innerHTML)//<a href="#">风龙废墟</a>
//outerHtml 获取对象的标签+对象内的标签+文本
console.log(p.outerHTML)//<p>异世相遇,尽享美味</p>
console.log(div.outerHTML)//<div> <a href="#">风龙废墟</a> </div>
p.innerHTML='踏鞴砂'
//p.outerHTML='踏鞴砂' 不推荐
//innerText获取对象内的文本
console.log(div.innerText)//风龙废墟
console.log(div.outerText)//风龙废墟
console.log(div.textContent)//( 空格 ) 风龙废墟
div.innerText='无想的一刀'//覆盖a链接,和innerHtml效果一样
div.outerText='无想的一刀'//覆盖a链接,和outerHtml效果一样
</script>
</body>
</html>
了解:文本结点的操作
appendData(txt)
向节点追加数据
insertData(start,txt)
向节点中插入数据
replaceData(start,num,txt)
替换节点数据
deleteData(start,num)
删除节点数据
substringData(start,num)
截取节点数据
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div>2.1版本还有一个月就要更新了</div>
<button type="button">appendData</button>
<button type="button">insertData</button>
<button type="button">replaceData</button>
<button type="button">deleteData</button>
<button type="button">substringData</button>
<script type="text/javascript">
var div=document.querySelector('div');
var text=div.firstChild
console.log(typeof div.innerHTML)//string
console.log(text.nodeName)//#text
//获取按钮
var btn=document.querySelectorAll('button')
btn[0].onclick=function(){
text.appendData('高兴')
}
btn[1].onclick=function(){
text.insertData(0,'原神')
}
btn[2].onclick=function(){
text.replaceData(0,3,'雷电将军')
}
btn[3].onclick=function(){
text.deleteData(0,3)
}
btn[4].onclick=function(){
var res=text.substringData(0,3)//(start,length)
console.log(res)
}
</script>
</body>
</html>
9.7文档结点
文档的属性:
body
title
cookie返回当前所有的cookie
文档的方法:
write()
writeln()
open()打开文档流
close()关闭文档流
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>genshin</title>
</head>
<body>
<script type="text/javascript">
//获取title内容
console.log(document.title)
console.log(document.body)
console.log(document.domain)
console.log(document.lastModified)//最后一修改时间
document.writeln('文档流输出')//换行
document.write('文档流输出')
</script>
</body>
</html>
9.8js操作css样式
obj.style.css属性
注意:
1、css属性若为border-radius等类型,需要驼峰命名法获取borderRadius
2、js中不能直接通过style获取内嵌式或者外部引入样式的css的属性值
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<style>
.two{
width: 300px;
height: 300px;
}
</style>
<body>
<div style="width: 300px;height: 300px;background-color: plum;">
</div>
<div class="two">
</div>
<script src="getStyle.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
var div=document.querySelector('div');
console.log(div.style.width)
console.log(div.style.height)
//设置css属性
div.style.backgroundColor="red"
div.style.borderRadius="10px"
//js无法获取css设置的样式,只能获取行内的
var two=document.querySelector('.two');
console.log(two.style.width)//获取不到
var res=getStyle(two,'width');
console.log(res)
</script>
</body>
</html>
js无法获取css设置的内嵌或引用的样式,只能获取行内的。解决办法引入js函数:
function getStyle(obj,name){
if(window.getComputedStyle){
return getComputedStyle(obj,null)[name];
}else{
return obj.currentStyle[name];
}
}
10.事件
事件:元素在某种特定的情况下触发了javascript的函数。任何的元素都可以触发事件
10.1事件绑定
方式一:
<div onclick = "fun()"></div>
方式二:
box.onclick = function(){
console.log('绑定方式二')
}
取消事件绑定
box.onclick = null;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
div{
width: 300px;
height: 50px;
background-color: aquamarine;
margin: 2px auto;
text-align: center;
line-height: 50px;
}
</style>
</head>
<body>
<!-- 方式一 -->
<div onclick="mclick(e)">胡桃</div>
<div>甘雨</div>
<script type="text/javascript">
//事件绑定
function mclick(){
console.log(1111)
}
//方式二
var div=document.querySelectorAll('div')[1]
div.onclick=function(e){
//ie低版本不能识别事件e,使用window.event可以获取
//解决兼容性
var e=e || window.event
console.log(e)
console.log(222)
}
//取消事件绑定
setTimeout(function(){
div.onclick=null
},2000)
</script>
</body>
</html>
10.2事件冒泡
当元素触发某个事件(比如onclick)后,向父级元素(从里往外)去不断的触发,直到最顶层位置,则为事件冒泡
普通浏览器到window为止 IE浏览器到document为止
但是部分事件没有事件冒泡:blur focus onload onunload…
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
.outer{
width: 500px;
height: 500px;
background-color: pink;
margin: 0 auto;
}
.inner{
width: 200px;
height: 200px;
background-color: lightskyblue;
margin: 20px auto;
}
</style>
</head>
<body>
<div class="outer">
<div class="inner"></div>
</div>
<script type="text/javascript">
var outer=document.querySelector('.outer');
var inner=document.querySelector('.inner');
outer.onclick=function(){
console.log('outer!!')
}
inner.onclick=function(e){
console.log('inner!!')
/**
* 解决事件冒泡
* W3C stopPropagation()
* IE cancelBubble=true
*/
//解决事件兼容
var e=e || window.event;
//W3C
//e.stopPropagation()
//IE
//e.cancelBubble=true
// 兼容写法
e.stopPropagation ? e.stopPropagation() :e.cancelBubble=true;
}
</script>
</body>
</html>
10.3事件信息获取
事件内第一个参数一般设置为event 或者e等,该参数获取事件当前的信息
IE低版本只支持window.event
兼容性写法:var ev = e || window.event
获取事件触发的信息
currentTarget获取事件最顶层的触发元素
(当不存在事件冒泡时,currentTart和target的效果一致)
target获取当前触发该事件的元素
type返回当前事件类型
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<button type="button">按钮</button>
<script type="text/javascript">
var btn =document.querySelector('button');
btn.onclick=function(){
var e= e || window.event;
console.log(e)
console.log(e.currentTarget)
console.log(e.target)
console.log(e.type)//click
}
</script>
</body>
</html>
10.4鼠标事件
onclick鼠标单击
ondblclick鼠标双击 click*2
onmousedown鼠标按键按下
onmouseup鼠标按键弹起
onmouseover鼠标移入 hover = onmouseover + onmouseout
onmouseout鼠标移出
onmousemove鼠标被移动
onmouseenter鼠标进入 (该事件不进行冒泡)
onmouseleave鼠标离开 (该事件不进行冒泡)
oncontextmenu当右键菜单展开触发
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
div{
width:300px;
height:50px;
background:lightblue;
margin:2px auto;
}
</style>
</head>
<body>
<div onclick="clickMe(this)">onclick</div>
<div ondblclick="clickMe(this)">ondblclick</div>
<div onmousedown="clickMe(this)">onmousedown</div>
<div onmouseup="clickMe(this)">onmouseup</div>
<div onmousemove="clickMe(this)">onmousemove</div>
<div onmouseover="clickMe(this)">onmouseover</div>
<div onmouseout="clickMe(this)">onmouseout</div>
<div onmouseenter="clickMe(this)">onmouseenter</div>
<div onmouseleave="clickMe(this)">onmouseleave</div>
<script>
function clickMe(obj){
obj.style.background = 'pink';
}
// document.onmousemove = function(){
// console.log('鼠标正在移动')
// }
</script>
</body>
</html>
10.5阻止事件默认行为
阻止事件默认行为(常适用于具有默认行为的元素)
具有默认行为的元素:1、超链接 2、表单 3、右键菜单
preventDafult()适用于W3C标准的浏览器
returnValue=false IE阻止默认行为的方法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
div{
width:100px;
height:300px;
background:lightblue;
display:none;
}
</style>
</head>
<body>
<div></div>
<a href="http://www.baidu.com">百度</a>
<script>
// 当右键菜单被打开则触发
document.oncontextmenu = function(e){
var e = e || window.event;
// 阻止默认行为 W3C
e.preventDefault();
console.log(e)
// IE低版本采用returnValue = false
// 兼容性写法:
e.preventDefault ? e.preventDefault() : e.returnValue = false;
var div = document.querySelector('div');
div.style.display = 'block'
console.log('右键菜单被打开')
}
var a = document.querySelector('a')
a.onclick = function(e){
var e = e || window.event;
e.preventDefault()
console.log('超链接被点击')
}
</script>
</body>
</html>
10.6键盘事件
onkeydown键盘按键按下
onkeyup键盘按键弹起
onkeypress键盘按键按下并弹起
10.7页面事件
onload 页面加载完成时执行
onunload 页面退出时执行
onresize 页面大小调整时执行
onscroll 页面滚动条滚动时执行
onmousewheel 鼠标滚动时执行(判断鼠标是上滑还是下滑)
//页面加载时
window.onload=function(){
console.log('load..')
}
//页面关闭
window.onunload=function(){
console.log('closed...')
}
//窗口大小发生改变时触发,检测退出全屏
window.onresize=function(){
console.log('窗口大小改变了...')
}
//滚动条滚动
window.onscroll=function(){
console.log('scrolling...')
//scrollTop获取滚动过后区域的高度,兼容性
console.log(document.documentElement.scrollTop || document.body.scrollTop)
console.log(document.documentElement.scrollHeight)
}
10.8表单事件
onfocus 元素获得焦点
onblur 元素失去焦点
onchange 域的内容被改变(select下拉框)
onsubmit 确认按钮被点击(该事件绑定在form表单)
onreset 重置按钮被点击
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
input{
border-radius: 10px;
}
.active{
border: 3px solid red;
outline: 0;
border-radius: 10px;
}
</style>
</head>
<body>
<form action="" method="" id="from">
姓名:<input type="text" id="user" /> <br>
密码:<input type="password" /><br>
<input type="submit" value="提交"/>
<input type="reset" value="重置"/>
<select name="character" id="character">
<option value="甘雨">甘雨</option>
<option value="七七">七七</option>
<option value="钟离">钟离</option>
<option value="胡桃">胡桃</option>
</select>
</form>
<script type="text/javascript">
var user=document.querySelector('#user');
user.onfocus=function(){
this.setAttribute('class','active')
}
user.onblur=function(){
this.removeAttribute('class')
//获取输入框中的内容
console.log(this.value)
}
var character=document.querySelector('#character')
//监听改变的时候
character.onchange=function(){
console.log(this.value)
}
//不推荐下面的写法
character.onclick=function(){
console.log(11122333)
}
var from=document.querySelector('#from')
//onsubmit、onreset是对整个表单进行的操作
from.onsubmit=function(){
return true; //允许提交 false 不允许提交, 判断用户名等表单信息是否填写完整
}
from.onreset=function(){
var res=confirm('确认要重置嘛?')
return res
}
</script>
</body>
</html>
10.9鼠标/键盘信息获取
button获取鼠标具体哪个按键按下
标准浏览器 0->左键 1->滚轮 2->右键
在IE中 1->左键 2->右键 4->滚轮 5->左键+滚轮 6->右键+滚轮 7->三者同时按下
keyCode 对于 keydown 事件,该属性声明了被敲击的键生成的 Unicode 字符码
左->37 上->38 右->39 下->40
which 返回键盘敲击按键生成的unicode编码
检测键盘是否按下特定的键,返回boolean (按下->true 没按下->false)
ctrlKey 检测键盘是否按下ctrl键
shiftKey 检测键盘是否按下shift键
altKey 检测键盘是否按下alt键
screenX 获取鼠标当前在屏幕上的X坐标
screenY 获取鼠标当前在屏幕上的Y坐标
clientX 获取鼠标当前在视窗上的X坐标
clientY 获取鼠标当前在视窗上的Y坐标
offsetX 获取鼠标当前距离操作元素的X坐标
offsetY 获取鼠标当前距离操作元素的Y坐标
移动小方块实例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
.box{
width: 300px;
height: 300px;
background-color: lightskyblue;
left: 0px;
top: 0;
position: absolute;
}
</style>
</head>
<body>
<div class="box"></div>
<script src="getStyle.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
var box =document.querySelector('.box');
box.onmousedown=function(e){
var e1=e || window.event;
// var ran=Math.floor(Math.random()*256);
// var op=Math.floor(Math.random()*1)
// box.style.backgroundColor="lightgreen";
// console.log(getStyle(box,'width').slice(0,3))
// console.log(window.innerWidth)
document.onmousemove=function(e){
var e2=e || window.event;
console.log(e1.offsetX)
console.log(e2.clientX)
// 边界条件判断
if(e2.clientX>=e1.offsetX && e2.clientX<=window.innerWidth-(getStyle(box,'width').slice(0,3)-e1.offsetX)){
var innerX=e2.clientX-e1.offsetX;
}
if(e2.clientY>e1.offsetY && e2.clientY<=window.innerHeight-(getStyle(box,'height').slice(0,3)-e1.offsetY)){
var innerY=e2.clientY-e1.offsetY;
}
box.style.left=innerX+'px'
box.style.top=innerY+'px'
// console.log('x:'+e.clientX)
// console.log('x:'+e.offsetX)
}
}
document.onmouseup=function(){
document.onmousemove=null;
box.style.backgroundColor="hotpink";
}
</script>
</body>
</html>
10.10事件句柄
addEventListener(eventName,Listener,false)绑定事件 冒泡的方向(false true)
false->从里向外 true->从外往里
removeEventListener()移除事件
attachEvent(eventName,Listener)绑定事件(IE)
detachEvent()移除事件(IE)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
div{
width: 200px;
height: 200px;
background-color: lawngreen;
}
</style>
</head>
<body>
<div></div>
<script type="text/javascript">
var div=document.querySelector('div')
//可以支持同时绑定多个事件
div.addEventListener('click',function(){
console.log(111)
})
div.addEventListener('click',function(){
console.log(222)
})
var listener1=function(){
console.log(333)
}
var listener2=function(){
console.log(444)
}
div.addEventListener('click',listener1,false)
div.addEventListener('click',listener2,false)
//移除事件
setTimeout(function(){
div.removeEventListener('click',listener1)
},2000)
</script>
</body>
</html>
兼容性封装方法:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
div{
width: 200px;
height: 200px;
background-color: lawngreen;
}
</style>
</head>
<body>
<div></div>
<script type="text/javascript">
var Listener={
add:function(obj,eventName,callback){
//判断是否为IE浏览器
if(obj.addEventListener){
obj.addEventListener(eventName,callback,false)
}else{
obj.attachEvent('on'+eventName,callback)
}
},
remove:function(){
if(obj.removeEventListener){
obj.removeEventListener(eventName,callback)
}else{
obj.detachEvent('on'+eventName,callback)
}
}
}
var div=document.querySelector('div')
Listener.add(div,'click',function(){
console.log(111)
})
</script>
</body>
</html>
11.ES5中的this绑定
在ES5中this存在绑定问题(this的指代和其调用的位置有关),而ES6中无this的绑定(this只和其定义的位置有关,和调用的位置无关)
this的一个宗旨:this指代永远都是当前对象
11.1this在普通函数中被调用
//1.this在普通函数中被调用,this指代全局对象window
var name='宵宫';
function fun(){
var name='早柚'
console.log(name)//早柚 局部变量和全局变量同时存在,优先使用局部变量
console.log(this.name)//宵宫 this指代当前对象window
console.log(this==window)//true
console.log(this===window)//true
}
fun()
11.2this在对象内调用
方式一:this指代实例化对象
//2.this在对象内调用
//方式一:this指代实例化对象
var obj={
name:'早柚',
age:20,
play:function(){
console.log(this==obj)
//建议不写obj,改写为this
console.log(obj.name)
console.log(obj.age)
console.log(this.name)
console.log(this.age)
}
}
obj.play()//true
方式二:this作为实参传入
<button type="button" onclick="demo(this)">button</button>
//方式二:this作为实参传入,传入的为当前操作的对象
function demo(obj){
console.log(obj)
obj.style.background='green'
}
方式三【重点】
li{
width: 200px;
height: 50px;
margin: 5px;
background-color: aqua;
}
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
//方式三:
var oLi=document.querySelectorAll('ul li')
for(var i=0;i<oLi.length;i++){
//为当前对象定义一个属性index接收i的值
oLi[i].index=i;
//var index=i;
oLi[i].onclick=function(){
console.log(this.index)
this.style.background='red'
//console.log(oLi[i]) //拿不到下标
}
}
方式四【易错点】
<h2>异世相遇,尽享美味</h2>
//方式四:易错点
var h2=document.querySelector('h2')
h2.onclick=function(){
console.log(this)//h2
var _this=this;
var that=this;
setTimeout(function(){
console.log(this)//指向window了,因为定时器内的函数为普通函数
_this.innerHTML='genshin impact'
},1000)
}
方式五:三和四的叠加使用
需要的功能效果:点击1s之后改变颜色
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
li{
width: 200px;
height: 50px;
margin: 5px;
background-color: aqua;
}
</style>
</head>
<body>
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<script type="text/javascript">
var oLi=document.querySelectorAll('ul li')
for(var i=0;i<oLi.length;i++){
oLi[i].index=i
oLi[i].onclick=function(){
console.log(this.index)
var that=this
setTimeout(function(){
oLi[that.index].style.background='red'
},1000)
}
}
</script>
</body>
</html>
11.3this在构造函数中使用
//自定义构造函数
function test(name,age){
//构造函数内的this指代当前实例化对象dog
//定义属性
this.name=name;
this.age=age
this.play=function(){
console.log(this.name+'已经'+this.age+'岁了')
}
}
var dog=new test('poppy',1)
console.log(dog)
console.log(dog.name)
dog.play()//poppy已经1岁了
11.4this在apply(),call(),bind()中使用
//4.切换对象
//var name='早柚';
var charactor={
name:'宵宫',
age:18,
play:function(a,b,c){
console.log(a,b,c,this.name+'是新的五星火系角色')
}
}
charactor.play()
var obj={
name:'迪奥娜',
age:'10',
say:function(){
console.log(this.name+'是一个很好用的辅助角色')
}
}
obj.say()//迪奥娜是一个很好用的辅助角色
//apply(),call(),bind()切换对象
//没有传入参数,则代表全局对象window
obj.say.apply()//早柚是一个很好用的辅助角色
//代表charactor对象
obj.say.apply(charactor)//宵宫是一个很好用的辅助角色
//只有一个参数时和apply使用一样
obj.say.call(charactor)//宵宫是一个很好用的辅助角色
obj.say.bind(charactor)//没有输出
var res=obj.say.bind(charactor)
console.log(res)//返回一个函数
/**
* ƒ (){
console.log(this.name+'是一个很好用的辅助角色')
}*/
//apply() 数组 call() 数字 bind()数字
charactor.play.apply(obj,[1,2,3])//1 2 3 "迪奥娜是新的五星火系角色"
charactor.play.call(obj,1,2,3)//1 2 3 "迪奥娜是新的五星火系角色"
var res=charactor.play.bind(obj,1,2,3)//1 2 3 "迪奥娜是新的五星火系角色"
console.log(res)
res()//1 2 3 "迪奥娜是新的五星火系角色"
//eg:
var arr=[1,2,5,6,4]
var max=Math.max(arr)//获取不了 NaN
var max=Math.max.apply(Math,arr)//6
console.log(max)
apply、call、bind的区别
A.fun.apply(B,arr)将A对象切换为B对象,采用数组的方式传入参数
A.fun.call(B,arg1,arg2,arg3...)将A对象切换为B对象,需要一个一个单独传入参数
A.fun.bind(B,arg1,arg2,arg3...)将A对象切换为B对象,返回一个函数
12.缓存
12.1简介
缓存分类
- cookie
- session
- web Storage(localStorage sessionStorage)也叫做本地存储
12.2Cookie
cookie客户端缓存:
1、主要用于存储访问过的网站数据,存储浏览器的信息到本地计算机中,用于客户端和服务器端的通讯
注意:如果浏览器完全禁止cookie,大多数网站的基本功能都将无法正常使用,chrome浏览器不支持本地文件的cookie的读取
2、cookie的特点
- 以文本形式保存(.txt)
- cookie存储信息不安全(不能存放重要的信息)
- cookie中有域(domain)和路径的概念,浏览器是一个比较安全的环境,所以不同的域之间不能直接访问(js的同源策略限制)
协议 域名 端口全部一致才成为同一个域
http://localhost:3000
http://localhost/index:3000
4、cookie的常见信息
name cookie的名字(键)
value cookie存放的值
expires:指cookie过期的时间(该时间为世界时间 UTC时间)也成为格林威治时间
max-age:指cookie最大的存活有效期(单位:秒)
domain: 指的是cookie当前的域
path:指cookie当前的路径
size:指cookie存放的大小
secure:指cooke的安全属性
注意:expires和max-age的默认值为session
代表关闭浏览器,该cookie则清空、失效
5、cookie的设置和获取
//document.cookie设置获取获取cookie
function setCookie(name,value,minutes){
var now = new Date();
now.setMinutes(now.getMinutes()+minutes);
// 设置cookie
document.cookie = name+'='+value+';expires='+now.toUTCString();
}
将cookie的失效时间设置为过期时间,则cookie就清除了
setCookie('username',false,-1)
eg:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript">
//设置cookie两小时后失效
var time=new Date();
time.setMinutes(time.getMinutes()+120)
console.log(time)
document.cookie='name=hutao;expires='+time.toUTCString()
document.cookie='username=ganyu;path=/;max-age=3600'
console.log(document.cookie)
/**
* 封装一个setCookie的函数
* name cookie的名字
* value cookie的值
* expires 失效时间
*/
function setCookie(name,value,minutes){
var time=new Date();
time.setMinutes(time.getMinutes()+minutes)
document.cookie=name+'='+value+';expires='+time.toUTCString();
}
setCookie('qiqi',123,60)
//cookie若想失效,则需要让时间过期
setTimeout(function(){
setCookie('qiqi',false,-1)
},5000)
setCookie('qiqi',false,-1)
</script>
</body>
</html>
12.3Session
session 服务器端缓存
变量保存的数据会保存在服务器端,通过返回一个session Id 来区分不同的用户。session Id会保存在本地的cookie
12.4Web Storage
localStorage和sessionStorage的区别:
localStorage:关闭浏览器数据仍然存在,除非手动清除
sessionStorage:仅存在于会话期间(关闭浏览器失效)
localStorage和sessionStorage的方法:
length属性 获取缓存的数量
getItem(key)获取缓存
setItem(key,val)设置或修改缓存
removeItem(key)移除缓存(删除单个缓存)
clear()清空所有的缓存
12.5缓存之间的联系
在html4中cookie在客户端保存用户名和简单的用户信息,cookie存在以下问题:
1、cookie的大小被限制在4Kb
2、占带宽:cookie是随着http一起被发送的,因此发送cookie则浪费带宽
3、操作cookie非常繁琐(需要我们去封装setCookie getCookie)
web Storage(本地存储)和cookie的异同:
共同点:都保存在本地浏览器中,和服务器端的session的机制不同
生命周期(缓存存活的最大时间):
- cookie:会设置一个expires(max-age)则cookie会在指定的时间失效,若没有设置结束时间,则默认为session,关闭浏览器则失效
- localStorage:关闭浏览器数据仍然存在,除非手动清除
- sessionStorage:仅存在于会话期间(关闭浏览器失效)
存储数据大小
- cookie的存储大小最多4Kb
- localStorage和seesionStorage一般可存储5M或者更大
服务器通讯
- cookie:对服务器发起http请求时,每次都会将数据携带在http请求中,过多保存cookie则带来性能问题
- localStorage和sessionStorage:数据不是由每个服务器请求传递,而是只有在请求时使用数据,而不参与服务器的通讯
13.对象的封装和继承
什么是js的封装?
我们需要将一些属性和方法隐藏起来,所以我们将这些属性和方法进行封装。然后通过外部的一个特定的接口(公有的方法)调用
涉及知识:
公有属性、公有方法、私有属性、私有方法
13.1对象的封装
封装的优点:
1、良好的封装可以减少耦合性(了解高内聚低耦合)
高内聚低耦合参考:https://blog.csdn.net/fangkang7/article/details/82684819
2、类的内部结构可以自由修改
3、可以对成员进行精确的控制
4、隐藏信息,实现细节
//最简单的封装
var person={
name:'宵宫',
age:16,
say:function(){
console.log(this.name+'今年'+this.age+'岁')
}
}
person.say()
console.log(person.name)
//构造函数
function Person(name,age,sex){
//公有属性
this.name=name;
this.age=age
//私有属性
var sex=sex
//公有方法
this.say=function(){
console.log('我的性别为:'+sex)
}
}
//公有属性
var people=new Person('早柚',18)
console.log(people)//Person {name: "早柚", age: 18}
//私有属性
var people=new Person('早柚',18,'女')
console.log(people)
people.say()//我的性别为:女
console.log(people.sex)//undefined
判断对象的所属关系
js中的安全模式:instanceof 判断是否由当前对象创建
instanceof判断结果为Boolean,属于则为true 不属于为false
13.2对象的继承
继承的意义:继承其实就是当多个方法存在相同的属性和方法时,就把这些相同的属性和方法提取到一个公共的方法中。
继承方式:
- 通过原型prototype继承
- 使用apply()、call()方法去继承
function Person(name,age,sex){
this.name=name;
this.age=age;
this.sex=sex;
this.show=function(){
console.log(name+'今年'+age+'岁了,是一个'+sex+'孩子!')
}
}
var sayu=new Person('早柚',16,'女')
console.log(sayu)
sayu.show()
// 继承,方式一
//定义一个学生
function Student(score){
this.score=score
//通过this切换对象,this在构造函数中使用,指代实例化对象
//Person.apply(this,[name,age,sex])
Person.call(this,name,age,sex)//这里不建议使用bind切换对象
}
var yoimia=new Person('宵宫',18,'女',90)
console.log(yoimia)
yoimia.show()
// 方式二 通过prototype继承【推荐使用】
Teacher.prototype=new Person('优菈',20,'女');
function Teacher(type){
this.type=type
}
var teacher=new Teacher('教授')
console.log(teacher.name)//优菈
teacher.show()
13.3非对象的继承
浅拷贝:
var aa={
name:'胡桃',
city:['重庆','北京','上海']
}
var bb=aa
bb.nam='甘雨'
console.log(aa)
console.log(bb)
var obj={
name:'胡桃',
city:['重庆','北京','上海']
}
// 浅拷贝
function copy(obj){
var newObj={}
//对象遍历
for(var key in obj){
newObj[key]=obj[key]
}
return newObj
}
var newObj=copy(obj)
newObj.name='七七'//这里赋新值之后拷贝的新数组的值也跟着改变了
console.log(obj)
console.log(newObj)
深拷贝:
当复制的对象里面的属性含有引用类型时(object),浅拷贝复制之后,对原对象的引用类型的值进行改变时,新复制的对象的值也会跟着原对象而改变。
var obj={
name:'胡桃',
city:['重庆','北京','上海']
}
// 深拷贝
function deepcopy(obj,arr){
var newObj=arr||{}
//对象遍历
for(var key in obj){
//判断赋值的是否为值类型
if(typeof obj[key] =="object"){
newObj[key]=obj[key].constructor == Array? []: {}
deepcopy(obj[key],newObj[key])
}else{
newObj[key]=obj[key]
}
}
return newObj
}
var newObj=deepcopy(obj)
newObj.name='七七'
obj.city.push('西藏')
console.log(obj)
console.log(newObj)
console.log(obj.city.constructor ==Array)//true
14.正则表达式
正则的作用:
*1、表单验证(检测用户名、密码等是否符合规范)
2、查找字符串
3、查找替换并替换
定界符
/正则规则/
原子
1、每一个字符都称为一个原子(数字、字母、下划线以及任何符号,包括空格)
2、每一个[]代表一个原子,中括号内为可选字符
[]号内的简写:
[0-9]代表0-9的任意一个数
[0-9A-Za-z_]代表数字、字母、下划线中的任意一个字符
注意:在[]内开头出现^,代表除了[]内以外的字符
3、{}代表重复匹配前面的原子
{m}重复匹配前面的原子m次
{m,n}重复匹配前面的原子至少m次,至多n次
{m,}重复匹配前面的原子至少m次
特殊的原子:
\d 代表0-9的任意一个数 相当于[0-9]
\D 代表除了0-9以外的任意字符 相当于[^0-9]
\w 代表数字、字母、下划线中的任意一个字符 相当于[0-9A-Za-z_]
\W 代表除了数字、字母、下划线以外的任意一个字符 相当于[^0-9A-Za-z_]
\s 代表所有的空白符(如:空格、换行、制表符)
\S 代表除了空白符以外的任意字符
元字符
. 代表任意一个字符
* 代表重复匹配前面的原子任意次 相当于{0,}
? 代表重复匹配前面的原子至少0次,至多1次 相当于{0,1}
+ 代表重复匹配前面的原子至少一次 相当于{1,}
模式修正符
i 不区分大小写
g 全局匹配
m 识别换行符
注意:模式修正符放置在定界符之外
定义正则表达式
// 方式一:通过定界符定义(推荐使用)
var pattern = /aaa/;
// 方式二:通过对象原型定义
var pattern = new RegExp('aaa');
严格模式
^必须以指定的字符开头 $必须以指定的字符结尾
必须完全符合正则表达式规则,才会验证通过
var pattern = /^[0-9A-Za-z_]{6}$/
贪婪模式
var pattern = /<li>.*<\/li>/;
var str = '<li>百事可乐</li><li>珍珠奶茶</li>';
var res = pattern.exec(str);
console.log(res)//<li>百事可乐</li><li>珍珠奶茶</li>
// 取消贪婪模式 .*?
var pattern = /<li>.*?<\/li>/;
var str = '<li>百事可乐</li><li>珍珠奶茶</li>';
var res = pattern.exec(str);
console.log(res)//<li>百事可乐</li>
正则的函数
exec()检测是否符合正则规则,将符合的部分以数组返回,不符合则返回null
语法:pattern.exec(str)
*test() 检测是否符合正则规范,返回Boolean值 符合->true 不符合->false
语法:pattern.test(str)
search()验证是否符合正则规则,返回字符第一次出现的下标
语法:str.search(pattern)
match()检测是否符合正则规范,将所有符合的内容全部以数组方式返回
(配合模式修正符g使用)
语法:str.match(pattern)
replace()将所有符合正则规则的内容进行替换
语法:str.replace(pattern,替换后的内容)
中文匹配
\u4e00-\u9fa5 中文的范围
var pattern = /[\u4e00-\u9fa5]/;代表任意的一个中文