javascript知识点整理--(基础语法,程序结构,内置对象,函数,BOM对象,DOM对象,正则,事件,对象/面向对象等,柯里化)等es5的所有知识点,后续将整理es6的

JS基础:脚本语言(编程语言)

作用:表单验证—减轻服务器压力

制作页面特效

动态改变页面内容

一、基础语法

1.定义

js是一种基于对象和事件的编程语言/脚本语言

2.特点

①交互----行为层(人机,机机)

②解释性语言—边解释边执行

翻译性语言分为:编译和解释两种,编译性语言以C语言为代表,速度快,跨平台性差

解释性语言以js为代表,速度稍慢但跨平台性好

3.组成部分

① ECMAscript 语法标准

② DOM 浏览器对象模型

③ BOM 文档对象模型

4.js在页面中的使用

在这里插入图片描述

5.变量

(1)定义

用来存储信息的容器

(2)声明和赋值

①先声明,后赋值

var i;
i = 1;

②同时声明和赋值

var i = 10;

延伸点:

①var声明的变量存在变量提升,只提升变量声明,

​ 全局的提升在js的开头,局部的提升在函数内部开头

②变量初始值为undefined

③变量可以连续声明,只用一个var,中间逗号隔开

var x = 1;
var y = 2;
var z = 3;
//简写:
var x = 1,y = 2,z = 3;
(3)命名规则

①由数字,字母,$ , _ 组成

②不以数字开头

③不用关键字和保留字 :if for……

④注意大小写

(4)种类及作用域

①全局变量

​ 声明在函数外,–判断变量类型

​ 在任何地方都可以用 --作用域

​ 始终保存在内存中 --生命周期

②局部变量

​ 声明在函数内 —判断变量类型

​ 只能在声明它的函数内部使用 ------作用域

​ 函数调用时才生效,其余状态为销毁 ----生命周期

6.数据类型及转换

(1)js的数据类型分为:值类型/原始类型和引用类型
(2)值类型分为:undefined 变量初始值
null 空值
number 数字(分为整数和浮点数、NAN)
boolean 布尔值(true、false)
string 字符串(所有用引号引起来的)
(3)可以用typeof()来检测数据类型

(4)数据类型转换

1.parseInt() 转换为整数

①parseInt() 转换为整数 (结果数据类型时number)

对于整数,返回本身,例如:parseInt(35); //35

对于浮点数。取整数部分 例如:parseInt(9.8) //9

对于数字开头的字符串,取数字部分,遇到非数字结束 例如:parserInt(“12a45”) //12

其余都返回NAN (特殊的Number)

2.parseFloat() 取浮点数

②parseFloat() 取浮点数

对于整数,返回本身,例如:parseFloat(35); //35

对于浮点数。取本身 例如:parseFloat(9.8) //9.8

对于数字开头的字符串,取数字部分,可以包含一个小数点,遇到非数字结束 例如:parserInt(“12.4.45”) //12.4

其余都返回NAN (特殊的Number)

3.Boolean() :转换为布尔值

undefined、null、数字0、NAN、false、空字符串,转换为布尔值时返回false,其余都返回true

4.number() 转换为数字

null、false、空字符串、空格字符串 返回0

true 返回1

undefined、NAN、有内容的字符串 返回NAN

其余返回本身

5.String() 转换为字符串

直接给括号里的内容加引号,

括号内是字符串,返回本身

6.弱类型转换:浏览器自动处理
7.运算符

在这里插入图片描述

在这里插入图片描述

8.获取节点的方法
①通过id名获取

获取的是一个,document.getElementById(“id名”);

②通过标签名获取

获取的是集合, document.getElementsByTagName(“标签名”),从页面中获取所有的这个标签名的标签

如果只需要获取同一个父级内的所有相同标签名的子标签,

父标签的变量名.getElementsByTagName(“子标签名”)

<ul class="list"  id="tab">
	<ul>
		<li></li>
		<li></li>
		<li></li>
	</ul>
	
	var bg=document.getElementById("bg") //获取父级ul
	var bgLi=document.getElementsByTagName("li");//从父级ul中获取所有li
③通过name名获取

获取的是集合,document.getElementsByName(“name名”),从页面中获取所有的有这个name名的标签,适用于获取不在同一个父级内的,或者是不同的标签

<div id="one">
	<p name="four">p2</p>
	<div name="four"></div>
</div>

<div name="four"></div>
	var four=docuemnt.getElementsByName("four"); //通过name名获取
④通过class名获取

获取的是集合,document.getElementsBuClassName(“class名”),从页面中获取所有的有这个class名的标签,适用与获取不在同一个父级内的,或者是不同的标签,但是class一样即样式一样的标签

<div>
	<p class="red">p2</p>
</div>

<div class="red">div4</div>
<ul>
	<li class="red"></li>
<ul>

var red = document.getElementsByClassName("red");
9.给节点内添加内容

语法:节点.innerHTML = “新内容”

新内容可以是文本,也可以是标签,会覆盖之前的原有的内容

10、定时器(计时事件)

①setInterval(匿名函数/函数名,毫秒数)

开定时器,每隔多长时间就执行一次 , 水滴石穿

关定时器,clearInterval(开的定时器的值) 关定时器需要时机(满足条件或者触发事件);

关闭定时器后再调用需要重新调用定时器

例:// 开启定时器,让轮播动起来
	var time = setInterval(封装的函数,1000);
	// 移进ban关闭定时器
	ban.onmouseover = function(){
		clearInterval(time);
	}
	// 移出ban,让轮播继续动
	ban.onmouseout = function(){
		time = setInterval(封装的函数,1000);
	}
// 定时器内调用匿名函数
			var t = setInterval(function(){
				console.log("a");
			},1000)


			var num = 0 //变量num
			// 声明的具名函数, 再定时器内调用
			function fn(){
				num++;
				console.log(num);
				if(3>2){
					console.log(454);
				}

				if(num == 5 ){
					clearInterval(t);
					clearInterval(t2);
				}
			}
			// 定时器内调用有/具名函数
			var t2= setInterval(fn,1000);
11、this 当前对象,属性和方法是谁的,谁就是当前对象
for(var i=0;i<pic.length;i++){//循环div中所有图片
	pic[i].index=i;//因为点击图片时,for循环已经结束,i的值为4,所以将i存储在自定义属性index中;
	pic[i].onclick=function(){//给图片点击事件
		//将点击的图片设为body的背景图片,this是关键字,表示当前对象,点那张图,哪张图就是当前对象
		body[0].style.backgroundImage="url(images/)"+(this.index+1)+".jpg";
	}
}

二、程序结构

1、定义

程序结构又叫程序控制,是对所写的程序,按照一定的顺序来执行

程序是一系列有序指令的集合

2、分类

①顺序结构(一般执行这个)

②选择结构(遇到需要二选一、多选一的时候)

③循环结构(重复执行的时候用这个)

3、选择结构

二选一:
①语法

if(条件){

​ 条件为真执行的代码

}else{

​ 条件为假执行的代码

}

②代码
if(a == "爱"){
	alert("爱");
}else{
	alert("321");
}
多选一:
①语法

if(条件1){

​ 条件1为真执行的代码

}else if(条件2){

​ 条件2为真执行的代码

}else{

​ 以上条件都为假执行的代码

}

注意:if有且只有一个,else if是根据代码需要可以有一个或者多个 else可以省略,省略后表示条件为假不做任何操作,不省略的话只能写一个

②代码
if(a == "爱"){
	alert("爱");
}else if( a == "不爱"){
	alert("321");
}else{
	alert("321");
}
switch
①语法

switch(表达式){

​ case 常量1:

​ js执行语句1;

​ break;

​ case 常量2:

​ js执行语句2;

​ break;

​ default:

​ js执行语句;

}

注意:break必须写才能有多选一的效果,switch是严格验证:===的验证,input框中value是字符串;

②代码
switch(a)
{
	case “1”:
	alert("1");
	typeof(a);
	break;

	case "2":
	alert("2");
	break;

	default:
	alert("g");
	break;
}

条件运算符(改写简单的二选一的结构

input1.value == "我爱你"?alert("我们结婚吧"):alert("分");

)

4、循环结构

①定义

在满足条件的情况下, 重复执行某些操作

②好处/优点

增强代码的简洁性,可维护性,可读性

③分类

for for…in while do…while

④for、
语法结构

for (初始条件 ; 循环条件/判断条件 ; 迭代条件) {

​ 循环执行语句;

}

初始条件:从哪里开始

循环/判断条件:到哪里结束

迭代条件:下一次从哪里开始

执行顺序

在这里插入图片描述

代码:

1-10
for(var i = 1; i <= 10; i++){
	document.write(i+"<br>");
}
⑤ for … in

用于循环数组或第项, 数组可以用for循环,也可以用for … in 循环,对于对象只能用for … in 来循环

// <!-- for …… in 用于循环数组 -->
		var num = [1,2,3,4,5,6,7,8,9,10]  //数组
		for (j in num){
			console.log(num[j]);
		}
		// for 循环数组
		for(var j = 0 ; j <num.length; j++){
			console.log(num[j]);
		}
		// for … in  用于循环对象的属性   键值对
		var obj={
			name:"张三",
			age:22,
			sex:"man"
		}

		// 循环对象
		for (m in obj){
			console.log(m);  //对象的属性名 --键
			console.log(obj[m])  ;// 对象的属性值  --值
		}

⑥ while

语法

初始条件;

while(循环条件){

循环操作/重复执行的语句;

迭代条件;

}

代码
// while
		var i=1;
		while(i<=10){
			document.write(i);
			i++;
		}

// do ……  while
		var i=1;
		do{
			console.log(i);
			i++;
		}
		while(i<=10);
⑦ do … while
语法

初始条件;

do{

​ 循环操作/重复执行的语句;

​ 迭代条件;

}

while(循环条件)

⑧跳转语句break和continue

break用于结束循环/switch选择/函数,他后面代码不再执行

continue用于退出本次 循环,后面的继续,(只能用于循环)一般可用于筛出敏感信息等…

⑨for … of

简洁,只需要值不需要索引时可使用 可用于字符串和数组

var str = "1234";
for(var val of srr){
	console.log(val);
}

var arr = [1,23,3,4]
for(var v of arr){
	console.log(v);
}

三、内置对象

对象是由属性(固有特征)和方法(能做什么)组成的特殊数据类型

对象分为:内置对象(js封装好,可以直接使用的)和自定义对象(自己创建的对象)

万物皆对象:世界万物都可以通过属性和方法来进行描述

1、Math对象

①定义

用于处理数学任务,注意:没有构造函数

②属性

Math.PI : 返回圆周率

③方法
(1)Math.abs(x) : 计算绝对值
(2)Math.ceil(x):上舍入
(3)Math.floor(x):下舍入
(4)Math.max(x,y,z……n):返回最大值
(5)Math.min(x,y,z……n):返回最小值
(6)Math.pow(x,y):x的y次幂
(7)Math.random():返回0-1之间随机数
(8)Math.round(x):四舍五入
(9)Math.sqrt(x):返回平方根
总结:

可以用来取整的方法有:(2) (3) (等价于parseInt) (8);

*获取区间随机数
12-25之间随机数
12+(25-12)*Math.random()

2、Date对象

(1)、定义

处理日期和时间,Date对象称为日期对象

(2)创建

①不传参, 表示当前时间

var body = mew Date();

②传参 表示指定时间,传参格式:“月日期 , 年份 , 时:分:秒”

var zhi = new Date(“7 30,2020,20:10:00”);

(3)方法

① 年 日期对象.getFullYear() 4位数

② 月 日期对象.getMonth() 0-1之间整数

③日 日期对象.getDate() 1-31之间整数

④ 时 日期对象.getHours() 0-23之间整数 24小时制

⑤分 日期对象.getMinutes() 0-59之间整数

⑥ 秒 日期对象.getSeconds() 0-59 (同上)

⑦星期几 日期对象.getDay() 0-6 星期日是0

⑧毫秒数 日期对象.getTime()

3、数组

(1)定义

用单独的变量名来存储一系列的值

(2)创建对象的方法

①用构造函数创建

②语法糖方式 []

//1.创建数组并赋值,
			//。先创建/声明后赋值
			var arr= new  Array();   //构造函数的方法创建数组
			var aar2 = [];   //【】语法糖方式创建数组


			// 创建/声明同时赋值
			var arr3 =new Array(7,8,9); //构造函数的方法创建数组
			var arr4=[1,2,3,4];

(3)分类
①密集数组

数组之间无间隔

②稀疏数组

数组元素之间有间隔

(4)操作数组:
(4)读取数组元素–查

数组名[元素的索引,下标]

对于密集数组而言,for循环和for……im循环都能读取元素中的每个元素

对于稀疏数组而言,for循环都能读取数组中的每个元素,没有值的返回undefined,for……in循环只会读取数组中的有内容的每个内容中的每个元素,没有值可以跳过

for循环中变量的值可以改变 for……in循环中的变量手动修改无效,始终按照 变量++的方式进行

	//1.创建数组并赋值,
			//。先创建/声明后赋值
			/*var arr= new  Array();   //构造函数的方法创建数组
			var aar2 = [];   //【】语法糖方式创建数组

			arr[0] = "a";
			arr2[0] = "2的第一个";*/



			// 创建/声明同时赋值
			var arr3 =new Array(7,8,9); //构造函数的方法创建数组
			var arr4=[1,2,3,4];


			// 值读取某个指定的元素
			数组名【指定元素的下标】,如num[2]
			//for循环读取数组中的每一个元素
			var num = [1,2,3,4,5,6];
			for(var i  = 0;i<num.length;i++){
				console.log(num[i]);
			}


			var shu = ["a",,,,"b",1,]//稀疏数组,,
			//用for……in循环读取数组中的每个元素
			for(j in num){
				console.log(num[i]);
			}
(5)增加数组元素 —4种 —增

①直接赋值法

​ ①数组名[索引]=内容 如:var arr=[]; arr[4] = “bb”;

②数组名.push(需要添加的内容 1个或多个) 添加到末尾

③数组名.unshift(需要添加的内容 1个或多个) 添加到开头

④数组名.splice(要添加的元素的索引,0,要加的内容1,要加的内容2……)在指定位置添加元素

//2.方法
			var num=[0,1,2,3]
			// console.log("数组原本内容:"+num);
			// ②数组名.push(需要添加的内容  1个或多个)  添加到末尾
			var p = num.push("A");
			console.log("push之后返回的内容:",p);  //返回数组的长度
			console.log("push之后数组的内容"+num);  //[0,1,2,3,"a"]

			// ③数组名.unshift(需要添加的内容  1个或多个)添加到开头
			var p = num.unshift("b");
			console.log("unshift之后返回的内容:",p);  //返回数组的长度
			console.log("unshift之后数组的内容"+num);  //["a",0,1,2,3]

			// ④数组名.splice(要添加的元素的索引,0,要加的内容1,要加的内容2……)在指定位置添加元素
			var p = num.splice(3,0,5,6,7);
			console.log("splice之后数组的内容:"+num);
(6)删除数组元素 —3种 —删

①数组名.pop()删除最后一个

②数组名.shift()删除第一个

③数组名.splice(要删除的元素的索引,删除的个数)删除指定位置的元素

④给数组的length重新赋值,从后面删除1个或多个

//2.方法
			var num=[0,1,2,3]
			// console.log("数组原本内容:"+num);
			// ①数组名.pop()  删除最后一个
			num.pop();
			console.log("pop之后数组的内容:"+num);

			// ②数组名.shift()  删除第一个,
			注意删除后,数组中后面的元素的索引会往前
			num.shift();
			console.log("pop之后数组的内容:",num);

			// ⑤数组名.splice(要删除的元素的索引,删除的个数): 删除指定位置的元素
			var p = num.splice(2,1);
			console.log("splice之后返回的内容:"+p);  //返回删除的元素
			console.log("splice之后数组的内容:"+num); 
			
			//④给数组的length重新赋值,从后面删除1个或多个
			var  varr = [1,2,3,4]
			arr.length = arr.length-n;
			n为1时删除末尾一个,
			n为2时,删除末尾2个
			…………………………
(7) 改写数组元素 —2种 --改

①直接重新赋值 优点:简单, 弊端:改写内容多,代码冗余

var num=[0,1,2,3];
num[2] = "L";
			console.log("改写后内容为:",num);  //[0,1,"L",3]

②数组名.splice(要改写的元素的索引,改写的个数,要改写的内容1,要改写的内容2……)在指定位置改写元素

var num=[0,1,2,3];
num.splice(0,3,"a","b","c"); //从索引为0开始,改写3个,该些内容分别是:"a","b","c"
			console.log("改写后内容",num); //["a","b","c",3];
(8)数组名.reverse() 颠倒/反转数组元素的顺序
var num=[0,1,2,3]

num.reverse();  //颠倒/反转数组元素的顺序
console.log("反转后数组的内容",num); //[3,2,1,0];
(9)排序

纯字母排序

①数组名.sort() 字母排序:字母按照a-z,首字母相同比较下一位

var ziMu = ["apple","pear","banner","cofe","milk","beef"];
			ziMu.sort(); //排序
			console.log("排序后数组为:",ziMu);

纯数字的数组排序

②数组名.sort()(function(a,b){return a-b}); 从小到大,如果要从大到小,就改写b-a即可,或者直接在后面加.reserve();

var shu = [1,5,24,30,100,2];
			shu.sort();
			shu.sort(function(a,b){return a-b});// function(a-b){return a-b}比较函数,从小到大,如果要从大到小,就改写b-a即可,或者直接在后面加.reserve();
			console.log("排序后",shu);
(10)不改变原数组的方法

①数组1名.concat(数组2,数组3……)合并数组元素

var arr=[1,2,3,4];
var z = ["a","b",3,4];
var x=[9,10];
var he=arr.concat(z,x);
console.log(he);  //新数组:1,2,3,4,a,b,3,4,9,10

②数组名.join(分隔符): 将数组中的元素用分隔符连接为一个字符串

var arr=["bannn","time",10]
var str = arr.join("--");
console.log(str); //bannn--time--10

③数组名.slice(开始的索引,结束的索引) 截取数组某个部分 包前不包后

var num=[1,2,3,4,5,6];
var sliArr=num.slice(2,5);
console.log(sliArr);//【3,4,5】

④.数组名.indexOf(指定的元素,从哪里开始找) 查找指定元素的索引

第二个参数可以不写 ,不写默认从索引为0开始找,写了就从写的位置开始找,没找到返回-1,找到了返回指定元素的索引,如果有多个,返回找到的第一个索引
var str=[3,2,"b",4,5,"b"];
console.log(str.indexOf('b'));//找到了返回指定元素的索引 2 多个,返回找到的第一个
console.log(str.indexOf("a"));//没找到返回-1
console.log(str.indexOf("b",3));//5  第二个参数写了就从第二个位置开始找

⑤数组名.lastIndexOf(指定的元素,从哪里开始找),从右往左找找到了返回的索引是从左往右,其他同indexOf()

var arr=[3,2,"b",4,5,"b"];
console.log(arr.lastIndexOf("b"));//5;
console.log(arr.lastIndexOf("b",4));//2;
(5)判断是否为数组(数组的检测)
Array.isArray(数组名)

​ //Array.isArray();
​ //isArray 是方法
​ //Array 对象
​ //Array 是函数
​ //Array 是一个当作对象处理的函数
​ //isArray 是什么? [静态方法]

//判断传入的值是否是数组  【返回值是布尔值】
			console.log(Array.isArray([]));
			console.log(Array.isArray(""));
			console.log(Array.isArray(undefined));
			console.log(Array.isArray(null));
			console.log(Array.isArray(false));

			//数组求和
			function sum(arr){
				// 判断是否是数组
				if(Array.isArray(arr)){
					var res = 0;
					for(var i = 0;i<arr.length;i++){
						res += arr[i];
					}
					return res;
				}else{
					console.log("参数arr必须是数组")
				}
				
				
			}
			console.log(sum([1,2,3]));  //6
			console.log(sum("123")); //参数arr必须是数组
			console.log(sum(false)); //参数arr必须是数组
(6)遍历(迭代方法)
forEach(value,index,array)

//Array是一个类别 它规定数组的实例一定具备有forEach的方法
var arr = new Array(1,2,30);

		//forEach中的函数执行的次数和数组长度有关﹐【相等的关系】
		arr.forEach(function(value,index,arr){
			
		})

		// forEach回调函数的第一个参数是 数组的第一项的值
		// forEach回调函数的第三个参数是当前数组
		//  forach回调函数的第三个参数是当前数组
例子:
	var arr2 = [4,45,2,5464,212,98];
			arr2.forEach(function(value,index,arr){
				if(index % 2 ==0 ){
					arr[index] = Math.pow(value,3);
				}if(index % 2 ==1 ){
					arr[index] = Math.pow(value,2);
				}
				//array[index] = Math.pow(value,index % 2=== 0 ? 3 : 2);
			})
			console.log(arr2);
map(value,index,array)

​ // 参数 回调函数(callback/cb/fn)
​ //作用 遍历/迭代/循环
​ //返回值 一个操作过的新数组

eg:

		//把原数组的每一项加1  不改变原数组
		
		// 基础操作
		var arr = [1,3,5,7,9];
		var res = [];
		for(var i = 0;i<arr.length;i++){
			res[i] = arr[i]+1;
		}
		console.log(res);

		// map操作
		// 对值得操作
		arr.map(function(value){
			return value += 1;
		})

		// 复制一个新数组
		var newArray = arr.map(function(value){
			return value;
		})

		//value值得下标次幂
		var newArray1 = arr.map(function(value,index){
			return Math.pow(value,index);  
		})
		console.log(newArray1);  // [1, 3, 25, 343, 6561]
filter(value,index,array)

​ //filter
​ //参数 callback
​ //作用是筛选数组元素
​ //返回一轮筛选得新数组

var arr  = [1,2,3,4,5,7];
arr.filter(function(value){
	//条件
	return value % 2 ==0;
})

// 找出数组中能够被索引整除
var arr1 = [10,12,50,2,70,90]
var newArray = 						    arr1.filter(function(value,index){
	return value % index === 0;
})
console.log(newArray);  //[12, 50, 90]

//去重
var arr2 = [1,1,2,3,2];
// indexOf 永远只找第一个元素得索引
arr2.filter(function(value,index,array){
	return array.indexOf(value) == index;
})
some && every

​ //some 一些
​ //参数 cb
​ //判断数组中得是否存在一个满足条件得元素
​ //返回值 boolean

			[0,1,1,1].some(function(value,index,array){
				return value === 0 ;
			})  //true

​ //every 全部
​ //参数 cb
​ //判断数组中是否全部都满足条件
​ //返回值boolean

			[0,1,1,1].every(function(value,index,array){
				return value === 1 ;
			}) //false
reduce

reduce 中的prev代表前一个值 reduce从一开始遍历

		//includes 在指定范围内查找
		//findIndex 判断是否存在并返回索引
		//index 判断是否存在
		//find 判断是否存在并返回值
		var arr = [1,2,3,44,5,6,7]
		console.log(arr.includes(44))//true,返回的是布尔值
		console.log(arr.indexOf(44)>-1)
	
		//数组.includes(要查找的数字,从哪里开始找)
		//在索引大于3的范围内查找是否存在44
		console.log(arr.includes(44,4))
(7)查找
findIndex

查找满足要求得第一元素得索引 [数组得实例方法]

			var arr = [11,22,33]
			var res = arr.findIndex(function(value,index,array){
				// console.log(value,index);
				return value ===22;
			})
			console.log(res); //1

			var res1 = arr.findIndex(function(value){
				return value > 22;
			})
			console.log(res1);  //2
find

查找满足要求得第一元素 [数组得实例方法]

			var arr1 = [33,22,11];
			var res2 = arr1.find(function(value,index){
				return index > 2;
			})
			console.log(res2) // undefined
(8)递归
			//找规律
			//特殊值
			//规律
			function fn(n){
				if(n === 1 || n ===2){
					return 1;
				}else{
					return fn(n-1) + fn(n-2);
				}
			}
			console.log(fn(4));


			function f(n){
				if(n < 4){
					return n;
				}else{
					return f(n-1) + f(n-2) +f(n-3);
				}
			}
			console.log(f(6));

			//所有非特殊值最终都会通过特殊值表达
(9) 数组扁平化

//数组扁平化 将n维数组转化为一维数组 flat(参数) 参数代表将其多少次扁平化 参数为Infinity时为无限

		ar arr1 = [1,2,3]; 
		var arr2 = [1,[2],3]
		var arr3 = [1,[2,[3]]]

		console.log(arr2.flat())
		console.log(arr3.flat(Infinity))
		
		var arr1 =[11,2,3]
		// reduce 是需要return的
		// reduce 中的callback prev = array[0]|| returnValue
		var a = arr1.reduce(function(prev,value,index,array){
			console.log(prev,value,index,array)
			return prev+value
		})

		reduce  中的prev代表前一个值  reduce从一开始遍历

4、String对象

(1)定义

用引号引起来的文本是字符串,String对象用于处理字符串

(2)创建
①构造函数

var str = new String(“abc”);

②语法糖

var str = “de123”;

(3)属性
①length
var str = "a我 bcd-7";
console.log(str.length);//8

总结:

①汉字、字母、空格、特殊字符、数字占一个长度,负数是一个连接符+一个数字

②和数组length的比较:

相同:从1开始的正整数

不同:数组的length可以修改/重新赋值,会影响数组。字符串具有稳定性,length修改无效

(4)方法
①改变大小写

总结:只对字母有效,原字符串不变,改变大小写后字符串是新字符串,整体改写

			var str = "a我 bcA-7";
			console.log(str.toLowerCase()); //a我 bca-7
			console.log(str.toUpperCase()); //A我 BCA-7
			
②截取字符串/字符
字符串.charAt()

字符串.charAt(索引号)返回索引号对应的字符 1个, 返回最后的,中间的,都可以和length搭用

			var str = "abcdef";
			console.log(str.charAt(0)); //"a"
			console.log(str.length-1); // 取末尾
			console.log(parseInt(str.length/2));; //取中间

字符串.slice()

字符串.slice(开始索引,结束索引)开始索引必写,结束索引选写,不写默认是原字符串的length

			var str = "12abc";
			console.log(str.slice(2,5)); //"abc";
			console.log(str.slice(4));//c
字符串.substring()

用法同slice();

区别:substring的参数不可以为负数,为负数时不报错但结果不可控

​ slice方法结束索引参数不可以为负数,负数表示从末尾开始

var str = "m2abc";
console.log(str.slice(1,-1)); //"2ab";
console.log(str.substring(1,-1));//"m"结果不可控
字符串.substr()

字符串.substr(开始索引,子字符串长度)开始索引必写,可以为负数,负数表示从末尾开始,子字符串长度可选,不写默认是原字符串的length

var str = "abcde1234";
str.substr(1,4); //bcde
str.substr(1);//"bcde1234"
字符串.valueOf()

返回原字符串

字符串.toString()

将括号里的内容加上引号,变成字符串,同数据类型转换里的String()

③返回索引 2个

字符串.indexOf(“指定字符/字符串”,从哪个索引开始查找),第一个参数必写,第二个参数选写,不写默认是0,返回值是第一个参数从第二个参数索引开始,找到的首次出现的这个字符/字符串的索引,没有找到返回-1

var str = "abcdefg123g4";
			console.log(str.indexOf("g"));//6  从索引0开始找,找到f后的g
			console.log(str.indexOf("g4",8));//10 从索引8开始找,找到3后的g
			console.log(str.indexOf("g1",8));//-1 没找到
			console.log(str.indexOf("g1"));//6 f后面的g1

lastIndexOf()

字符串.indexOf(“指定字符/字符串”,从哪个索引开始查找),第一个参数必写,第二个参数选写,不写默认是length-1,返回值是第一个参数从第二个参数索引开始从后往前找,找到的首次出现的这个字符/字符串的索引,没有找到返回-1

			var str = "abcdefg123g4";
			console.log(str.indexOf("g"));//10  从索引0开始找,找到f后的g
			console.log(str.lastIndexOf("g1"));//6 字符串默认从索引0开始找,
			console.log(str.indexOf("g4",8));//-1 从索引8开始找,没找到
			console.log(str.indexOf("g1",8));//6 */
④字符串.repeat(次数)

将字符串重复/复制指定次数,生成新字符串

⑤字符串.split()

将字符串切割为一个数组

			var str = "I Love You";//创建字符串
			console.log(str.split()); //["I Love You"]  不传参,整个字符串作为数组的元素

			var arr1 = str.split(" "); //传参,以所传参数把字符串分割为数组的多个元素
			console.log(arr1); //["I","LOVE","You"];

			var arr2 = arr1.reverse();//对数组使用反转方法
			console.log(arr2); //["You", "Love" ,"You"];

			var arr3 = arr2.join(); //对反转后的数组使用join拼接为一个字符串
			console.log(arr3; //"You Love I"
⑥字符串.trim()

去掉字符串首尾的空格,注意字符串中间的空格不会被去掉

			var str = "          abc          "
			console.log(str); //本身

			var str2 = str.trim(); //去掉字符首尾的空格
			console.log(str2);
⑦字符串.replace()

替换字符串字符

// 字符串的replace方法  【字符串】
			var str = "hello";
			console.log(str.replace("l","*")); //he*lo;
			console.log(str); //字符串的不可变性//稳定性

5.正则表达式

字符匹配
(1)定义

用于搜索和替换的字符串搜索模式,该模式可以是单个字符,也可是复杂的规则

(2)语法
/正则表达式主体/修饰符(i,g,m)

正则表达式的主体是根据项目的需求,由自己按照语法规范来编写,修饰符仅有三种:i :不区分大小写 , g :全局匹配 , m :多行匹配

(3)语法规范

https://www.runoob.com/jsref/jsref-obj-regexp.html

核心要点:

[]---表示范围
[0-9] [a-z] [A-Z] [A-z]
()

元字符  大写的取反
\w 找单词字符
\d 找数字
\s 找空格
\n 找换行

量词--次数
{x}  {x,}  {x,y}  n+

方法:
正则.test(字符串)  :检测字符串是否符合正则,返回布尔值
字符串.replace(正则,替换的内容)	:把找到的符合正则要求的内容用第二个参数替换 
(4)代码范例

正则:表示一个对应规范的字符序列【针对字符串】

两种匹配方式:匹配字符、匹配位置

			/*var phone = /^13797657366$/;
			console.log(phone.test("211379765736632"))//false*/
			// 普适性  对一类字符串普遍适用


			//人{1}狗{2,3}
			var str1 = "abc";				
			var str2 = "abbc";				
			var str3 = "abbbc";				
			var reg1 = /^ab{1,3}c$/; 		
			console.log(reg1.test(str3));	//true
			console.log(reg1.test(str2));	//true
			console.log(reg1.test(str1));  //true


			// 把str5 中的满足reg1正则表达式规则的字符片段取出  保存在数组中返回
			var str4 = "abc  abbc  abbbc abbbbc";
			var reg2 = /ab{1,3}c/g;
			console.log(str4.match(/ab{1,3}c/g));   //["abc", "abbc", "abbbc"]
			console.log(str4.match(reg2));   //["abc", "abbc", "abbbc"]


			// test 是正则的方法,match是字符串的方法
			// 一个人溜两三只狗(金毛/哈士奇/泰迪)
			//人{1}[金毛哈士奇泰迪]{2,3}

			var str5 = "abc aac acc adc"
			var reg3 = /a[abcd]c/g;
			console.log(str5.match(reg3));   // ["abc", "aac", "acc", "adc"]

			//范围表示法 连字符"-";
			// [123456] => [1-6];


			var str6 = "1a2 1-2 1z2";
			var reg5 = /1[a\-z]2/;
			var reg6 = /1[az-]2/;
			var reg7 = /1[-az]2/;
			console.log(reg5.test(str6));   //true
			console.log(reg6.test(str6));	//true
			console.log(reg7.test(str6));	//true


			//排除字符组 使用脱字符^
			var str7 = "1a2 1-2 1z2";
			var reg8 = /1[^-]2/g;
			console.log(str7.match(reg8));  // ["1a2", "1z2"]

			//手机号正则
			//\d 数字【0-9】
			//\D 非数字[^0-9]
			var reg9 = /^1[35-9]\d{9}$/;

			// \w 表示英文数字下划线   [a-zA-Z0-9_]    [a-zA-Z\d_l]
			// \W 非英文数字下划线     [^a-zA-Z0-9_]

			var str8 = "1324sdsda__.....  "
			var reg10 = /\W/g;
			console.log(str8.match(reg10));  //[".", ".", ".", ".", ".", " ", " "]

			// \s 表示空白字符 [tv fn r]
			var str9 = "a b1b c";
			var reg11 = /[ab]\s[bc]/g;
			console.log(str9.match(reg11));   //["a b", "b c"]

			// 贪婪匹配和惰性匹配
			var reg14 =  /\d{2,4}/;
			var reg13 = /\d{2,4}/g;

			var reg15 = /\d{2,4}?/g; //加? 触发惰性匹配  尽可能少的去匹配
			var str10 = "1 12 123 1234  12345 123456";  

			console.log(str10.match(reg14));//['12'];

			// 贪婪匹配
			console.log(str10.match(reg13));//["12", "123", "1234", "1234", "1234", "56"]

			// 惰性匹配
			console.log(str10.match(reg15)); //["12", "12", "12", "34", "12", "34", "12", "34", "56"]
位置匹配
字符

^、$、\b、\B、(?=p)、(?!p)

匹配捕获

var reg = /(\d)\d\n/g;

\n表示与当前正则匹配到的第几个括号内内容一致

eg:

每个数组第一位和第三位相等

var str =  "121  313  515";

var reg = /(\d)\d\1/g;  表示与第一个括号内内容一致

var str1 = "12021 45654";
var reg1 = /(\d)(\d)\d\2\1/g;
console.log(str1.match(reg1));


var str2 = "312211";
var reg2 = /(\d)\1*/g;  没有特定位置时使用每次会切割之后从切割后字符串第一个数开始捕获
var arr = str2.match(reg2);
console.log(arr);

四、函数

声明函数:函数声明在哪里都可以

调用函数:函数在哪里调用就在哪里生效,有名函数有函数提升

1、定义

为实现一定功能得代码语句块,可以带参数和返回值,分为系统函数和自定义函数

2、常用系统函数

parseInt() parseFloat() Number() Boolean() String()

isNaN() undefined、NaN、非纯数字的字符串返回true 其余返回false

3、自定义函数

(1) 有名/匿名函数

行内调用的函数必须是全局函数(直接写在script标签内,外层没有函数)

		<button>点击</button>
		<button onclick="btnChange()">点击变色</button>
		<script type="text/javascript">
			console.log(a); //undefined
			console.log(btnChange); //btnChange的函数体
			
			var btn = document.getElementsByTagName("button")				[0];
			var body = document.getElementsByTagName("body")[0];
			// console.log(btn);

			//匿名函数  有赋值运算符,就可以封装匿名函数
			btn.onclick = function(){
				alert(11);
			}

			var a = function(){
				console.log("aaaa");
			}
			a();

			//具名函数  单独封装的函数必须写函数名  函数名取名规范同变量,			  存在函数提升,返回的是函数体
			function btnChange(){
				body.style.backgroundColor = "red";
			}

			</script>
(2)有参/无参函数 见函数.html

封装函数的思想:将相同逻辑封装,不同的内容设为参数,调用时传参

①形参

函数声明时的参数,本质是一个声明在函数内的局部变量,初始值是undefined

②实参

函数调用时的参数,实参传递给形参,相当于给变量赋值,实参必须是确定的内容,实参的个数顺序必须和形参保持一致

③实参列表–arguments

表示实参的集合,类似数组,可以用数组的一些方法

(3)带返回值的函数

①根据需求决定是否需要带返回值

②在函数内用return返回值,来返回函数的返回值,放在函数调用的地方

③return后的代码不再执行,即return有结束函数的效果

4、闭包

(1)简单闭包

在函数内读取函数外的全局变量

(2)复杂闭包

在函数外读取函数内的局部变量

直接读取会报错,需要利用链式作用域在函数内部再声明一个内部函数,将内部函数作为返回值返回

链式作用域:父对象的变量,子对象都可以操作,但是子对象里的变量,父对象不可操作

			function fn1(){ //外层函数  -- 父对象
				var num = 1;
				function fn2(){ //内层函数  --子对象
					num += 10;
					console.log(num);
				}
				
				return fn2; //将内部函数作为外层函数返回值
			}
				var res = fn1(); //调用外层函数,将返回值存在变量res中
				
				console.log(res); //存放的是内部函数的函数体
				
				res();//11 在fn1外读取到了fn1里面的num值
(3)闭包的优点
var btns = document.getElementsByTagName("button");
			// 1.全局变量计数  弊端 :全局变量哪里都可以用,别处徐改了它的值,计数不准确了
			var count = 0;
			btns[0].onclick = function(){
				count++;
				console.log(count);
			}
			count = 5;

			// 2.局部变量计数 每次都会给局部变量赋值为0,青瓷点多少次都是1
			btns[1].onclick = function(){
				var count2 = 0;
				count2++;
				console.log(count2);
			}

			// 3.闭包计数	优点:可以解决全局变量计数的弊端
			function wai(){//外层函数
				var count3 = 0;//外层函数的变量
				function nei(){//内层函数
					count3++;//内层函数里操作外层函数的变量
					console.log(count3);
				}
				return nei;//返回内层函数
			}
			var result = wai();//调用外层函数

			btns[2].onclick = function(){
				result();
			}
(4)闭包的缺点

会使父函数内的局部变量始终保存在内存中,造成内存泄漏/占用

五、BOM对象

1、定义

浏览器对象模型,核心对象:window对象,包括history对象,location对象,document对象

2、作用/功能

打开,关闭,调整浏览器窗口大小,移动,前进,后退等

3、window对象

(1)常用事件
①鼠标事件

onclick 单击鼠标左键;

ondblclick 双击鼠标左键

onmouseover 鼠标移入

onmouseout 鼠标移出

onmouseenter 鼠标进入

onmouseleave 鼠标离开

②键盘事件

onkeydown 键盘的按键按下

onkeyup 键盘按键松开

③界面(UI)事件

onload 窗口或图片加载完毕

onchange 域的内容改变

④域的内容改变事件
		var txt = document.getElementById("txt");
		txt.onchange = function (){
		txt.value = txt.value+"是个大坏蛋";
		}
(2)常用方法
①弹窗 都会阻塞进程

alert(11) :警示框 显示警示语 有一个确定按钮

prompt(“请输入:”) : 提示/输入框 显示提示语
有一个input框供输入内容,有确定和取消两个按钮,
点确定按钮会将输入内容存储,类型是字符串,点取消会存入null

confirm(); 确定框,显示提示语,有确定和取消两个按钮,点确当返回true 点取消返回false,一般和if搭配使用

②计时

笔记见基础语法10 计时

③open 打开新窗口

https://www.runoob.com/jsref/met-win-open.html

window.opem(url地址,在哪里打开,设置大小和位置)

4、history对象

(1)定义

本窗口的浏览历史

(2)方法
①history.back()

上一个等价于history.go(-1);

②history.forward()

下一个等价于history.go(1);

5、location对象

(1)定义

页面地址

(2)属性

location.host 返回主机名和端口号

location.hostname 返回主机名

location.href 返回完整的域名 也可以给他赋值,跳转到赋值的url页面

(3)方法

①location.reload() 刷新页面/重新加载

②location.replace(‘要跳转的页面的url地址’) 跳转到指定页面

6、document对象

(1)获取节点

见基础语法8

(2)修改内容

见基础语法9

(3)修改样式

①节点.style.样式名 = “新样式值”

②节点.style = “所有的样式声明”

③节点.setAttribute(“style”,“所有的样式声明”)

④节点.setAttribute(“class”,"‘类名’) 等价于 节点.className = “类名” (优点ss兼顾CSS中优先级和伪类效果)

(4)获取/设置/修改属性
①获取属性

节点.getAttribute(“属性名”)

②设置/修改属性(2种)

节点.属性名 = ”新的属性值“

节点.setAttribute(“属性名”,“属性值”)

六、DOM对象

1、DOM层次关系 查找结点

(1)找父节点

②子节点.parentNode

(2)找子节点

②父节点.firstElementChild //找第一个子节点

②父节点.lasteElementChild 找最后一个节点

(3)找兄弟节点

①兄弟节点.nextElementCild ,兄弟节点.nextElementSibling, 兄弟节点.nextSibling 紧跟兄弟节点下一个节点

(同previousSibling和previousElementSibling,nextSibling和nextElementSibling也是类似的。)

②兄弟节点.pafreviousElementChild 兄弟节点.previousElementSibling,兄弟节点.nextSibling 紧跟兄弟节点的上一个节点

(他们的区别是previousSibling会匹配字符,包括换行和空格,而不是节点。previousElementSibling则直接匹配节点。)

李晓燕语文95
	<script type="text/javascript">
		var tds = document.getElementsByTagName("td");

		/*console.log(tds[1]);

		console.log(tds[1].parentNode);//<td>语文</td>父级tr

		console.log(tds[1].parentNode.parentNode);//tr父节点 tbody;

		console.log(tds[1].parentNode.parentNode.parentNode);//tbody父级table;

		console.log(tds[1].parentNode.firstElementChild);//<td>李晓燕</td> 子级中包含空的文本节点,要找到第一个标签子节点就用父节点.firstElementChild,不用父节点.firstChild;

		console.log(tds[1].parentNode.lastChild);//空文本节点
		console.log(tds[1].parentNode.lastElementChild);//同first*/

		// console.log(tds[1].parentNode.childNodes);//包含空的文本节点,注意索引,少用

		console.log(tds[1].parentNode.firstElementChild.nextElementsiblimf)//<td>语文</<td>

		console.log(tds[1].parentNode.lastElementChild.potElementsiblimf)//<td>语文</<td>

2、节点操作的方法

(1)创建节点

document.createElement(“标签名”)

var img1 = document.createELment("img") ;//创建图片标签

注意:创建的节点没有增加到页面中时不可见,可以用(2)或(3) 增加到页面

(2)增加节点到末尾

父节点.appendElement(子节点名)

父节点.appendElement(img1); //添加节点到末尾

注意要点:添加给父级最后一个元素子节点

(3)增加节点到上面

父节点.insertBefore(新节点/兄节点,指定节点/弟节点)

父节点.insertBefore(兄节点,弟节点);
				// 上移
				spanUp.onclick = function(){
					var row = this.parentNode.parentNode.rowIndex;
					if(row <=1){
						alert("最大值,无法继续");
					}else{
						// 获取当前行
						var nowTr = this.parentNode.parentNode;
						// 获取上一行
						var nowFirst =nowTr.previousElementSibling;
						// 移动
						tb.insertBefore(nowTr,nowFirst);
					}
				}
				
				// 下移
				spanDown.onclick = function(){
					// 获取当前行
					var nowTr1 = this.parentNode.parentNode;
					// 获取下一行
					var nowFirst1 = nowTr1.nextElementSibling;
					console.log(nowFirst1);
					// 移动
					tb.insertBefore(nowFirst1,nowTr1);
				}
				
				
(4)克隆节点

父节点.cloneNode();

(无参)
p1.cloneNode();//克隆标签本身,包括声明的id,class等等
(有参)
p1.cloneNode();//克隆标签本身及其内容
1 var p = document.getElementsByTagName("p")[0];
2 var cP = p.cloneNode();//克隆p节点
3 var cP = p.cloneNode(true);//克隆p节点,深度克隆,克隆节点以及节点下面的子内容。
(5)删除节点

节点名.remove();

父节点.removeChild(子节点名);

var tdBack = this.parentNode;
tdBack.remove();s

fu.removeChild(childs[i]);
(6)替换节点

父节点名.replaceChild(新的节点,要替换的节点)

fu.replaceChild(新的节点,要替换的节点)

3、js获取节点的样式

(1).window.getComputedStyle(节点名).样式名
var one = document.getElementById("one");
window.getComputedStyle(one).width;//只能读取,获取节点最终显示的样式,不管样式写在行内还是class里或者id选择器里.注意样式的驼峰命名:line-height写为lineHeigth  复合样式没有给值会显示默认值,颜色值都显示为rgb()
(2)只用于获取宽高

节点.offsetWidth, 节点.offsetHeight 或者 节点.clientWidth、clientHeight

			console.log(one.offsetWidth);
			console.log(one.offsetHeight);

			console.log(one.clientWidth);
			console.log(one.clientHeight);

注意:同:都返回数字,不带单位,都包括内容区+内边距,

​ 不同:offsetHeight/offsetWidth还包括边框 , (1)的方法带单位且只包括内容区

在没有边框,且box-sizing:border-box时,三种方式返回的数值都是一样的

七、事件

1、定义

在浏览器或文档中能被行为触发的特定的交互瞬间(你若触发,我便执行)

2、常用事件

(1)鼠标事件

onclick 单击

ondblclick 双击

onmouseover 移入

onmouseout 移出

onmouseenter 进入

onmouseleave 离开

onmousemove 移动

onmousedown 按下

onmouseup 松开

(2)键盘事件

onkeydown 按下

onkeyup 松开

onkeypress 按键经过

(3)表单事件

onforcus 获得焦点

onblur 失去焦点

onchange 域的内容改变

onreset 表单重置事件

onsubmit 表单提交

(4)UI界面事件

onload 图片或窗口加载

onresize 窗口或框架尺寸被调整

onscroll 滚动条事件

3、event对象

(1)定义

当前事件对象

(2)作用

获取鼠标位置、按键的keyCode

(3)注意浏览器兼容处理

var oEvent = e|| event

(4)要掌握的属性

event.type 当前事件对象的类型,即事件去掉on,如点击事件,返回click

event.clientX 当前鼠标位置的横坐标 (相对浏览器计算) 常用于做拖拽效果

event.clientY 当前鼠标位置的纵坐标 (相对浏览器计算)

event.offsetX 当前鼠标位置的横坐标 (相对标签节点计算) 常用于做放大镜效果

event.offsetY 当前鼠标位置的纵坐标 (相对标签节点计算)

event.keyCode 确定按下的是哪个键盘按键

event.traget 当前事件的目标节点

(5)应用

拖拽、放大镜

4、事件流

(1)定义

页面接收事件的顺序

(2)分类
①事件冒泡

由内往外接收事件,浏览器默认支持,冒泡的是行为,所以只有父子节点上绑定的是相同事件才会先触发内层节点上的事件,然后是外层节点上的事件

onmouseover onmouseout 默认有事件

onmouseenter onmouseleave 只能触发目标节点,不冒泡,

②事件捕获

顺序和冒泡相反,需要设定相应的参数才能实现

(3)阻止冒泡
functon stop(e){
	//处理浏览器兼容
	var oEv = e||event; //如果穿了实参,oEv变量里存储的是实参,如果没有传实参,就给默认值event
	if(oEv.stopPropagation){
		oEv.stopPropagation();  //阻止冒泡
	}else{
		oEv.stopPropagation = true;  ///IE低配版本浏览器,阻止冒泡		
	}
}

延伸:

//函数功能:修改指定节点的样式并阻止冒泡
//参数 obj目标节点
// cssstyle样式声明
//e当前事件对象,可选参数
/有无返回值:无
function fengFn(obj,cssstyle1,e){
	// obj.style = cssstyle1;//修改样式旳谷歌可以识别
	obj.setAttribute("style" ,cssstyle1);//修改样式―谷歌工E都能使用
}
//调用阻止冒泡的方法并处理好浏览器的兼容了
stopPro(e);

5、事件绑定的方法

(1)节点.事件名 = 匿名函数(在js内)
var odiv = document.getElementById("div");
odiv.onclick  = function(){
	执行代码;
}
(2)js内封装全局函数,在开始标签内用 事件名= “函数名(传参)”
html:
<div onclick = "fn(123)"></div>

js:
function fn(num){
	return num;
}
(3)使用事件监听.addEventListener(‘事件名’,匿名函数/有名函数函数名,布尔值)
var odiv = document.getElementById("div");
odiv.addEventListener('onclick',function(){
	执行代码
},true);

注意:事件名加引号,不加on,布尔值需要事件捕获,就传true,否则默认为false,不传参

6、事件监听–绑定事件的第三种方法

(1)语法

在这里插入图片描述

(2)优点–好处

①对同一个事件上绑定多个执行/回调函数,都能执行,别的方法只能执行最后一个执行函数

			//点击div1弹出123,456
			addEventHandler(div1,"click",alt);
			addEventHandler(div1,"click",alt2);
			
			function alt(){
				alert(123);
			}
			function alt2(){
				alert(456);
			}

②可以解除相应的事件绑定

只有用事件监听绑定的事件才能移出

			// 点击按钮,移出div1中的alt2
			addEventHandler(btn,'click',function(){
				removeEventHandler(div1,'click',alt2);
				// console.log(1);
			})

7、默认行为

(1)定义

浏览器自动添加的行为,如单击右键,弹出默认菜单,点击a标签,页面跳转/刷新,禁止图片拖拽等……

(2)阻止默认行为

①return false 写在函数最后一行

8、事件委托/代理

(1)定义

利用冒泡原理,将事件绑定在父级或祖先上来触发

(2)写法
var list  =document.getElementById("list"); //父节点
list.addEventLister = function(){
	var oEvn = e || event;
	oEvn.onclick = function(){
		
	}
}
(3)优点

①节省内存,运行更快,可以用console.time() ……console.timeEnd()来测试花费时间

②对js动态添加的节点,效果也能实现

八、对象/面向对象

1、定义

用抽象的方式,以现实世界为基础创建虚拟世界,是一种编程模式/思想

编程模式分为:面向过程,面向对象两种

2、面向对象和面向过程的比较

在这里插入图片描述

3、对象

js中万物皆对象,对象分为内置对象和自定义对象

(1)对象是由属性和方法组成的特殊的数据类型

(2)对象的属性和方法的使用

			console.log(today.name); //对象名.属性名
			console.log(today['name']);  //对象名['属性名']
			
注意:属性名如果是一个数字,就必须使用[]的方式来获取

方法使用:对象名.方法名(有参需要传参);

(3)对象的属性和方法可以自定义/扩展

默认对象
today.name = "好日子";
console.log(today.name); //对象名.属性名
console.log(today['name']);  //对象名['属性名']


//自定义方法
today.say = function(){
	console.log(today.getFullYear()+today.name);  //自定义属性
}
	today.say();

3、this – 当前对象
(1)指向
this指向属性和方法的左边的对象,对于全局便可而言,this指向window
对于局部变量内的this,它指向 = 左边对象

(2)动态作用域

作用域分为全局作用域和局部作用域,

变量定义的时候就确定了作用域,

this是执行/调用的时候,确定指向/作用域

4.创建对象

(1)自定义对象的本质

无序的键值对,键为属性名,值为属性值,方法是属性值为函数的特殊属性称为方法

(2)创建方式
①构造函数方式
			var people = new Object; //构造函数的方式创建   O必须大写
			people.name = "张三";		//给people对象添加属性
			people.sex = "男";
			people.age = 38;
			people.say = function(){  //给people对象添加方法
				console.log(this.name + this.age);
			}
			console.log(people);
②语法糖
			// 使用语法糖/对象字面量方式 在{}内写键值对,键和值之间用冒号隔开,每对之间用逗号隔开
			var peo2 = {
				name : "李四",
				age : 33,
				sex : "女",
				show:function(){
					console.log("姓名为:"+this.name+"今年"+this.age+"岁");
				}
			}
			peo2.show(); //调用方法

5、工厂模式

工厂模式是一种设计模式,是一种用来批量生产对象的具体步骤:

①封装函数 ②封装对象 ③将对象作为返回值返回

// 函数功能:批量生产商品
			// 参数:id  车牌号
			// 	 color  颜色
			function car(id,color){
				// 封装对象
				var car = {
					carId : id,
					carColor : color,
					showSay:function(){
						console.log("车牌为"+this.cardId+"颜色								是"+this.cardColor+",滴滴");
					}
				}
				return car;  //返回car对象
			}
			var playCar = car("Ef002","黑色");  //实例化对象

共仓模式的弊端:①看不出类型 ②对象的方法重复,资料浪费

6、构造函数

(1)定义

new关键字后面跟的函数,称为构造函数

构造(对象)函数 建造函数 按照你的意愿来创建对象

(2)构造函数和函数的的比较

同:都是函数

异:构造函数必须首字母大写,用来创建对象

​ 普通函数 函数名自定义,用来实现一般的功能

(3)构造函数和工厂模式的比较

①没有显示的创建对象

②属性和方法赋值都给this对象

③没有返回值

④可以解决工厂模式看不出的对象类型

7、原型和原型链

(1)、原型的定义

① 实例化的对象都有一个隐式原型属性:

在这里插入图片描述

② 构造函数有一个显示原型属性,prototype,都指向一个对象,我们称为原型对象

③ 显示原型对象中放的是公用的属性和方法,实例化的对象可以继承该原型对象上的属性和方法,解决资源浪费的问题

(2)、实例化对象可以访问的属性和方法

①实例化对象可以访问构造函数和原型对象上的属性和方法

② 相同的属性和方法,在构造函数和原型对象中都有,实例化的对象会访问构造函数中的属性方法

(3)、实例对象删除属性和方法

① 实例化对象可以删除从构造函数中得来的属性和方法,删除后再访问返回undefined

删除语法:delete 对象名.属性名/方法名

② 实例化对象从原型对象中继承的属性和方法只有访问权限,不能删除

(4) constructor 属性

实例化对象可以直接访问其构造函数 语法:实例对象名.constructor ;

(5)原型规则—理解原新链的基础

①所有的引用类型,数据类型都具有对象的特性,可以自由扩展属性和方法,null除外

引用类型分类:内置对象、自定义对象、系统函数、构造函数、自定义函数,null;

		function fn(){

			}
			console.log(typeof fn);  //function  自定义函数

			var obj1 = {};
			console.log(typeof obj1); //object  自定义对象

			var arr = [];
			arr.name = "数组";
			arr.say = function(){
				console.log("扩展")
			}
			console.log(arr.name);
			arr.say();

			fn.size = "大函数";
			console.log(fn,size);

			null不可以扩展属性和方法
			null.name = "null的名字";
			console.log(null.name)

② 所有的引用类型,都有一个 __ proto __ (隐式原型属性),属性值是一个对象

③所有的函数都有一个 prototype的属性,称为(显示)原型,属性值是一个对象 ;

function fn(){}
			console.log(fn.prototype);
			console.log(Date.prototype); //{constructor: ƒ, toString: ƒ, toDateString: ƒ, toTimeString: ƒ, toISOString: ƒ,……}

④所有引用类型的 __ proto __ 属性值指向它的构造函数的prototype的

ar obj = {};
			console.log(obj.constructor);//构造函数  Object

			console.log(obj.__proto__ == Object.prototype);

⑤ 需要得到一个引用类型的某个属性时,会先从本身去找,如果没有,就回去原型中找

function Peo(name){
				this.name = name;
			}

			// 如果没有,就回去从原型中擦找
			Peo.prototype = {
				sex : "man"
			}

			var obj1 = new Peo("张三丰");  //实例化
			// 需要得到一个引用类型的某个属性时,会先从本身去噪
			console.log(obj1.name);  //"张三丰"   会先从本身去找

			console.log(obj1.sex);  //man 从原型上查找

⑥ 原型链

原型链向上搜索,如果自己有就用自己的,自己没有就往原型上找,原型没有,继续往原型的原型上找,一直找到为止,如果找到原型链顶端还未找到,会返回undefined

形成原型链		
        	function Nao(){} //Nao构造函数
			Nao.prototype ={
				jie : "祖母绿"
			}//Nao的构造函数的原型独对象
			var n = new Nao();  //new后面调用Nao构造函数,实例化对象

			function Mather(){} //Mather 的构造函数
			Mather.prototype = n; //Mather的原型对象是实例化的Nao对象
			var m = new Mather(); //实例化Mather对象


			function Docter(){} //Docter构造函数
			Docter.prototype = m; //Docter的原型对象是实例化的m对象
			var  doc = new Docter();  //实例化Docter对象
			
			console.log(doc.jie);  //打印doc的jie触身  返回“祖母绿”;

⑦new关键字

new 关键字 修饰符 修饰函数调用
1.new 修饰函数调用和不修饰函数调用得相同点:
–函数逻辑如何执行

2.new修饰函数调用和不修饰函数调用的区别

​ --返回值:new修饰函数 调用默认返回空对象{},而且无法更改

​ --this指向:就是返回值

1.在函数内部默默创建空对象{}
2.将函数的this强制指向 上面创建的空对象
3.将空对象的_ proto _属性赋值为函数的静态属性prototype
4.将返回值指向this / 对象

⑧静态属性

函数上的属性叫静态属性

函数柯里化

是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术)

1.相较与普通函数而言函数柯里化的value值不会被调用重置或者说return会将其重新赋值

2.柯里化的函数后面有几个括号就说明它被传了多少次参数也就是它会被执行多少次

		    function f(name){

				f.value = (f.value || 0) + name + (name-1);
				// console.log(name);
				return f;
				
			}
			
			console.log(f(1).value);   			//1
			console.log(f(1)(2).value);   		//5
			console.log(f(1)(2)(3).value);      //14
			console.log(f(1)(2)(3)(4).value);   //30

AJAX

eg: //找爸要钱
// 需要进行通信 (数据交换)
// 通讯的设备
//你(客户端) 爸爸 (服务器) 通信设备(AJAX) 运营商(http);

AJAX技术的核心 - XMLHttpRequest 构造函数


扩展***************************************

函数:

函数的声明和变量

//在js中声明是需要变量的
// var关键字是定义变量的
// function 是声明函数的
// 任何声明都会提前
// 任何变量都有默认值 undefined
console.log(a) //undefined
var a = 123;//变量的声明与赋值
console.log(a)//123
b()//声明的函数可以被提前调用
// c()//定义的函数不能提前调用
// 声明b函数
function b(){}
// 定义一个c函数
var c = function(){}

//f(x) = x + 1
//f(5) = 6
// 按值传递
function f1(arg){
	console.log(++arg)
}
var a = 10
f1(10)//11
console.log(a)//10
// 按引用传递
function f2(arr){
	arr.pop()
	console.log(arr)
}
var b = [1,2,3]
f2(b);//[1,2]
console.log(b)//[1,2]

//值类型:占有空间小
//引用类型:占用空间大

//栈 速度快而空间小 [引用类型]
//堆 速度慢而空间大

在这里插入图片描述

参数和静态方法

//同一个函数,根据参数类型或者参数个数不一样,
//导致函数功能不一样就是函数重载 用if实现

//静态属性和静态方法
//把函数当做对象处理
//给函数添加属性称为静态属性
//给函数添加方法称为静态方法

//作用域
//局部作用域 任何函数都能形成局部作用域
//以函数名命名局部作用域 [[scope]]
//全局作用域 没有被任何函数嵌套的区域就是全局作用域[[scope global]]
//作用域的作用:作用域是取值的依据

//作用域和作用域链在函数定义的时候就决定了
//并且不会随着函数位置的变化
//函数的执行情况而变化

var b = 11
function f(){
	var a = 1;//在作用域中定义了一个变量a bing赋值为1
	console.log(a)//取值操作 优先查找当前作用域[[scope f]] 找到返回 找不到找全局变量
	console.log(b)
	// console.log(c)
}
//查找方向是 [[scope f]]--->[[scope globall]] 作用域链 --->null
//此时查找 b 是跨作用域查找 [跨作用域查找会消耗资源 会降低性能] 
//此时查找 c 整条作用域中都没有找到 c is not defined 
f()//1

//非特殊情况下,函数中this指向函数执行时离函数最近的对象
//在全局作用域上定义的变量就相当于在window对象上添加属性和方法
//全局方法执行 省略了window  

this指向

如何决定this指向

1.函数内有变量取值 (作用域和作用域链)
2.对象的(属性/方法) 取值 (原型和原型链)
3.函数中this的取值 (函数的执行状态、环境有关 / 看函数名前面的第一个对象是谁)

控制函数this的指向
function fn(){
console.log(this)
}
fn();//window

var o1 = {name:'o1'}
var o2 = {name:'o2'}
var o3 = {name:'o3'}



function changeThis(f,thisObj){
	thisObj.__f = f; //给对象添加一个f方法
	thisObj.__f();//执行一次
	delete thisObj.__f;//删除添加的方法
}
changeThis(fn,o1)//把fn里面的this指向o1
changeThis(fn,o2)
changeThis(fn,o3)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值