IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> JavaScript -> 正文阅读

[JavaScript知识库]JavaScript

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>

运行结果为:

image-20210723113704844

变量提升:代码在执行的时候,会将"var apple"这句语句提升在console之前。

image-20210723113857577

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()parseFloatNumber()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

image-20210726185938084

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>

image-20210729093546943

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#documentnull

结点特性:

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>

image-20210802151054697

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>

image-20210802141127631

	//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])

image-20210802150848839

元素节点获取

元素节点获取
获取单个元素:(直接返回元素节点)
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)

image-20210814104259347

深拷贝

? 当复制的对象里面的属性含有引用类型时(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

image-20210814104540033

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]/;代表任意的一个中文

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-19 11:57:40  更:2021-08-19 11:58:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/26 15:51:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计