自定义函数、数组基础、Dom、数组和字符串的api

143 阅读16分钟

自定义函数Function

一、创建

1、【声明方式】创建函数
	function 函数名(形参列表){
	函数体;
	return 返回值;
	}

2、【直接量方式】创建函数:
	var 函数名=function(形参列表){
	函数体
	return 返回值;
	} 

二、调用

var result=函数名(实参列表);

三、作用域

1.全局作用域:全局变量 和 全局函数,在页面的任何一个位置都可以使用
2.函数作用域:局部变量 和 局部函数,只能在【函数调用时,内部可用】

四、声明提前

原理:在程序正式执行以前,会将var声明的变量(轻)和function声明的函数(重),都会悄悄的提前到当前作用域的顶部,但是赋值留在原地
1.声明方式创建的函数会完整的提前(第一种)
1.1直接量方式创建的函数不会完整提前,只有变量名部分会提前(第二种)
2.何时使用:永远不会自己使用,干扰我们的判断 - 只会出现在笔试之中,为什么平时开发不会遇到呢?
只要你遵守以下规则:
	1、先创建后使用
	2、变量名和函数名尽量的不要重复

五、重载

相同的函数名,根据传入的实参的不同,自动选择对应的函数去执行,但是JS不支持,如果函数名重复了,后面的肯定会覆盖前面的
	目的:减轻我们程序员的压力,记住一个方法就可以执行很多的操作
	解决:在【函数内部】自带一个arguments的对象(类数组对象),不需要我们去创建的
        作用:哪怕没有写任何形参,它也可以接受住所有的实参,
	固定套路:
	1、通过下标去获取传入的某一个实参:arguments[i] - i下标是从0开始的!
	2、通过length去获取到到底传入了几个实参:arguments.length;
	通过判断传入的实参的不同,执行不同的操作,变相的实现重载操作

数组Attay的基础

概念:

数组都是线性排列的,除了第一个元素,每个元素都有唯一的前驱元素,除了最后一个元素,每个元素都有唯一的后继元素

一、创建数组

1、直接量方式:var arr=[];
	var arr=[数据1,...];
2、构造函数方式:var arr=new Array();
	var arr=new Array(数据1,...);

二、获取数组元素

数组名[i];//i为数组下标

三、添加、替换元素

数组名[i]=新数据;
如果下标处没人则为添加,如果下标处有人则为替换

四、数组的三大不限制

数组具有三大不限制:
1、不限制元素的类型
2、不限制元素的长度
3、不限制下标越界 - 不是好东西:
    如果获取元素时,下标越界,返回的是一个undefined
    如果添加元素时,下标越界,会得到一个稀疏数组,如果有一天我们搭配上学过的循环去遍历获取每个元素,那么你会得到很多很多的undefined

五、数组中有一个唯一的属性

语法:数组名.length
作用:获取数组的长度,长度是从1开始的
三个固定套路:
	1、向末尾添加元素:arr[arr.length]=新数据
	2、获取数组的倒数第n个元素:arr[arr.length-n];
	3、缩容:删除倒数n个元素:arr.length-=n

六、遍历数组

拿出每个数据来进行相同或相似的操作
固定公式:
1、向末尾添加元素:arr[arr.length]=新数据
2、获取数组的倒数第n个元素:arr[arr.length-n];
3、缩容:删除倒数n个元素:arr.length-=n

DOM:Document Object Model

一、DOM树概念

DOM将我们的HTML看作了是一个倒挂的树状结构,但是树根不是HTML标签,而是document对象
document对象:不需要程序员创建,由浏览器的js解释器自动创建,一个页面只有一个document树根
作用:可以通过树根对象找到我们想要的任何一个DOM元素/节点/对象(属性和方法)
页面上的每个元素、属性、文本、注释等等是一个DOM元素/节点/对象

二、查找元素

1.通过 HTML 的特点去查找元素

1、通过 ID 去查找元素:
	var elem=document.getElementById("id值");
	特殊:
	1、返回值,找到了返回当前找到的DOM元素,没找到返回一个null
	2、如果出现了多个相同id,只会找到第一个
	3、记住控制台输出的样子,这个样子才叫做一个DOM元素/节点/对象,才可以下午拿去做操作!
	4、忘记此方法,不允许使用,id不好用,一次只能找到一个元素,把id留给后端使用
	5、其实id根本不用查找,可以直接使用
2、通过 标签名 去查找元素:
	var elems=document/已经找到的某个父元素.getElementsByTagName("标签名");
	特殊:
	1、返回值,找到了返回的是一个类数组DOM集合,没找到返回空集合
	2、js只能直接操作DOM元素,不能直接操作DOM集合!解决:要么下标拿到某一个元素,要么遍历拿到每一个元素
	3、不一定非要从document开始查找,如果从document去找,会找到所有的元素,可以换成我们已经找到的某个父元素
3、通过 class名 去查找元素:
	var elems=document/已经找到的某个父元素.getElementsByClassName("class名");
	特殊:
	1、返回值,找到了返回的是一个类数组DOM集合,没找到返回空集合
	2、js只能直接操作DOM元素,不能直接操作DOM集合!解决:要么下标拿到某一个,要么遍历拿到每一个
	3、不一定非要从document开始查找,如果从document去找,会找到所有的元素,可以换成我们已经找到的某个父元素

2.通过 元素之间的关系 去查找元素:前提:至少要【先找到一个元素】才可以使用关系网

1、父亲:elem.parentNode;//单个元素
2、儿子:elem.children;//集合
3、第一个儿子:elem.firstElementChild;//单个元素
4、最后一个儿子:elem.lastElementChild;//单个元素
5、前一个兄弟:elem.previousElementSibling;//单个元素
6、后一个兄弟:elem.nextElementSibling;//单个元素

三、操作元素 前提:先找到元素,才能操作元素

1.内容

1、elem.innerHTML - 获取或设置开始标签到结束标签之间的内容,【支持识别标签的】
	获取:elem.innerHTML;
	设置:elem.innerHTML="新内容";
2、elem.innerText - 获取或设置开始标签到结束标签之间的纯文本,不支持识别标签的
	获取:elem.innerText;
	设置:elem.innerText="新内容";
以上两个属性都是专门为双标签准备的,而有一个但标签也是可以写内容:<input />,我们如何操作:
3、input.value; - 专门获取/设置input的内容
	获取:input.value;
	设置:input.value="新内容";

2.属性

1、获取属性值:elem.getAttribute("属性名");
2、设置属性值:elem.setAttribute("属性名","属性值");
简化版:
	1、获取属性值:elem.属性名;
	2、设置属性值:elem.属性名="属性值";
	注意:
	1class必须写成className
	2、只能操作标准属性,不能操作自定义属性

四、样式

使用样式的方式:3种
1、内联样式
2、内部样式表
3、外部样式表
在js中用的是内联样式
语法:
    获取样式:elem.style.css属性名;
    设置样式:elem.style.css属性名="css属性值";
注意:一切的获取,都是为了做判断!一切的设置,都是为了做修改!

五、绑定事件

elem.on事件名=function(){
	操作;
	关键字this - 这个,只能在【事件】内使用
		如果单个元素绑定事件,this->这个元素
		如果多个元素绑定事件,this->当前触发事件的元素!!!
}

数组的基础二

一、创建数组

1、直接量方式:var arr=[];
	var arr=[数据1,...];
2、构造函数方式:var arr=new Array();
	var arr=new Array(数据1,...);
new Array(num);创建了一个长度为num的空数组,里面没有任何东西,只有无数的undefined

二、hash(关联)数组:下标是可以自定义的

1.创建
    1、创建空数组:var arr=[];
    2、为数组添加自定义下标并且赋值:arr["自定义下标"]=新值
2、访问:arr["自定义下标"]
3、强调:hash数组的length会失效,永远为0!
	遍历hashfor in循环,不需要设置从哪里开始到哪里结束,纯自动化的,专门为了遍历hash数组而存在的
	语法:
		for(var i in 数组名){
		//i -> 下标
		//数组名[i] -> 当前次元素.
		}
不止hash数组可以遍历,也可以遍历索引数组
建议:索引数组依然使用forhash数组在使用for in
4、hash数组的原理:
	hash算法:将字符串,计算出一个尽量不重复的数字(地址值)
	 字符串内容相同,则计算出来的数字也一定是相同的
	添加元素:js解释器会将自定义下标交给hash算法,得到一个数字(地址值),直接将你要保存的数据放到此地址之中保存起来
	获取元素:js解释器会将指定的下标再次交给hash算法,得到一个和当初保存时完全一样的数字(地址值),通过此地址值就可以找到你当初保存的数据,取出来使用
5、js里面一切的东西都是对象,万物皆对象,除了undefined和null,一切对象的底层都是hash数组

数组 API

不会修改原数组的3个API

1、arr 转 str:join()
	var str=arr.join("自定义连接符");
固定套路:2个
	1、无缝拼接
	var arr=["h","e","l","l","o"," ","w","o","r","l","d"];
	console.log(arr.join(""))
        2、数组拼接
	var arr=["-请选择-","北京","南京","西京","东京","重庆"];
		var str="<开始>"+arr.join("</结束><开始>")+"</结束>";
		sel.innerHTML=str;

2、拼接数组:添加元素的新方式 concat()
	将你传入的实参全部拼接为arr的末尾
	var newArr=arr.concat(新值1,arr1,...);
	特殊:
	不修改原数组,只会返回一个新数组
3、截取子数组:只想取出数组中的某一个部分 slice()
	根据你传入的开始下标一直截取到结束下标
	var subArr=arr.slice(starti,endi+1);
	特殊:
	1、不修改原数组,只会返回一个新数组
	2、含头不含尾
	3、endi可以省略不写,如果省略不写,则从starti位置一直截取到末尾
	4、starti和endi都可以省略不写,那么从头到尾完整的复制一份,此操作也叫做深拷贝!复制了一个副本给对方,两者互不影响。
	5、支持负数参数,-1代表倒数第1个

会修改原数组的API

4、删插替:splice()
删除:var dels=arr.splice(starti,n);//n代表删除的个数
	特殊:虽然他直接修改原数组,但是也有返回值,返回的是被删除的数据组成的一个新数组,因为前辈们考虑到有可能删除的东西刚好是你需要的东西,哪怕没有删除也会返回一个空数组
插入:var dels=arr.splice(starti,0,新值1,...);
	特殊:
	1、原starti位置的元素以及后续元素都会向后移动
	2、尽量的不要插入一个数组,会导致我们的数组一些是一维,一些是二维,遍历的时候极不方便
替换:var dels=arr.splice(starti,n,新值1,...);
	特殊:删除的个数和插入的个数不必相同

5、翻转数组:arr.reverse();
    颠倒数组中元素的顺序

数组API二

1.数组排序:arr.sort()

语法
arr.sort(function(a,b){
    return a-b
    })
 a为前一个元素,b为后一个元素。
 return a-b;从小到大,升序排列
 return b-a;从大到小,降序排列
 a-b为正:则后一个大于前一个
 a-b为负:则后一个小于前一个
 a-b0:则后一个等于前一个
 sort方法会根据你返回的正数、负数、0自动考虑要不要交换位置

2.栈和队列:添加元素和删除元素

2.1:栈:其实就是数组,一端封闭,只能从另一端进出
用法:
开头插入元素:arr.unshift(新值1,新值2,...)
开头删除元素:arr.shift();每次只能删除一个,有返回值
结尾插入元素:arr.push(新值1,新值2,...)
结尾删除元素:arr.pop();每次只能删除一个,有返回值
2.2:队列:也是数组,可以一端进入另一端出
用法:开头进,结尾出
arr.unshift(新值1,新值2,...)
arr.pop()

用法:结尾进,开头出
arr.push(新值1,新值2,...)
arr.shift()

ES中的3组6个新API

1、判断:2个,判断的结果为布尔值

every:每一个,要求所有的元素都满足条件才为true,只要有一个不满足则为false,和逻辑运算符&&用法一致
var bool=arr.every(function(val,i,arr){
		//val - 当前的值
		//i - 当前的值的下标
		//arr - 当前数组本身
		return 判断条件;
})

some:有一些,要求只要有一个元素满足结果就为true,全部条件不满足结果才为false,和逻辑运算符||用法一致
		var bool=arr.some(function(val,i,arr){
		return 判断条件;
})

2、遍历:拿到数组中的每个元素做相同或相似的操作

forEach - 直接修改原数组
arr.forEach(function(val,i,arr){
	操作;
})

map - 不会修改原数组,返回一个新数组
var newArr=arr.map(function(val,i,arr){
	return 操作;
})

3、过滤和汇总

过滤:筛选出需要的部分,原数组不会发生变化的
var subArr=arr.filter(function(val,i,arr){
	return 判断条件;
})
汇总:
var result=arr.reduce(function(prev,val,i,arr){
	return prev+val;
})

箭头函数

专门简化一切的匿名回调函数

公式:
function去掉,()和{}之间添加=>
若形参只有一个,那么()省略
若函数体只有一句话,那么{}省略
若函数体只有一句话并且是return,那么{}和return都省略

二维数组

数组的元素,又引用着另一个数组 什么时候用:在一个数组,希望再次细分每个分类

创建:
var arr=[
	["张三",18,3500],
	["李四",19,4500],
	["王五",20,2500]
];
访问:数组名[行下标][列下标];

注意:下标越界
列下标越界:返回undefined
行下表越界:报错,因为行下标越界已经得到undefined了,undefined没有资格再加[]做操作

遍历二维数组:必然两层循环,外层循环控制行,内层循环控制列
for(var j=0;r<arr.length;j++){
	for(var i=0;c<arr[j].length;i++){
		console.log(arr[j][i])
	}
}

String的概念

1.什么是字符串:由于多个字符组成的【只读】字符【数组】
2.和数组有相同点:
	1、字符串中的个数:str.length
	2、获取字符串中的某个字符:str[i]
	3、遍历字符串
	4、所有数组不修改原数组的API,字符串也可以使用(concat、slice)

3.和数组不同的地方
	1.所有数组的直接修改原数组的API,字符串都不可以使用,比如排序只有数组可以使用,但是字符串也有很多很多属于自己的API

4.引用/对象类型:11String Number Boolean -> 包装类型
	Array Function Date(日期) Math(数学) RegExp(正则:验证)
	Error(错误)
	Object(面向对象)
	Global(全局对象) - 只不过在浏览器端被window对象给代替了,自然保存着全局变量和全局函数,只不过window可以省略不写,有一天我们会去学习node.js这个后端语言,而在node.js中全局对象就叫做global

5.包装类型:专门用于将原始类型的值封装为一个引用类型的对象的
    为什么:原始类型的值原本是没有任何属性和方法,意味着原始类型本身是不支持.去做任何操作的
    何时使用:只要试图使用原始类型的变量调用属性或方法的时候,自动包装
    何时释放:方法调用完毕后,自动释放包装类型,就又变成了一个原始类型的值
    注意:nullundefined不能使用;因为没有给他们提供包装类型

String的API

以下的API不会修改原字符串,只会返回一个新字符串

1、转义字符:\

    作用
    1将字符串中和程序冲突的字符转为原文
	" \" "	' \' '
       例:
       var str = "天下第\"\""
       输出为:天下第"一",把斜杠右边的的引号转为原文
       
    2包含特殊功能的符号:
	换行:\n
        例:
        var str="天下第一\n上天入地";
        在一字后后面换行
        
	制表符:\t,等价与TAB,大空格
        var str="天下第一\t上天入地";
        在一字后面插入一个空格
        
    3输出unicode编码的字符:\u
	汉字的第一个字:\u4e00 - ascii码:19968
	汉字的最后一个字:\u9fa5 - ascii码:40869

2、大小写转换:将字符串中的每个英文字符统一的转为大写或小写

何时:只要程序不区分大小写,就要【先统一】的转为大写 或 小写,再比较(做验证码)
	用法:
         var str="holl word"
        //转大写
        console.log(str.toLocaleUpperCase())
        //转小写
        console.log(str.toLocaleLowerCase())

3、获取字符串中的指定位置的字符

str.charAt(i)   ===   str[i]

4、获取字符串中的指定位置的字符的ascii码

var ascii=str.charCodeAt(i);
    
    通过ascii码转回原文:
    var 字=String.fromCharCode(ascii码);
    例:console.log(String.fromCharCode(ascii码));

5、检索字符串:检查索引 - 检查下标,获取关键字的下标

var i=str.indexOf("关键字",starti);
	从starti位置开始,查找右侧第一个关键字的第一个字符的位置
	starti可以省略,默认从0位置开始查找的
	返回值:找到了,返回的第一个关键字的第一个字符的下标位置
		没找到,返回-1,其实我们根本不关心下标为多少,我们只关心下标为不为-1
	作用:判断有没有!
	强调:数组也能使用此方法,数组这个方法其实是后期才添加上的,原本此方法只有字符串可用,比如老IE的数组就没有此方法
        
	笔试题:默认只能获取第一个关键字的下标,如何才能获取到所有的关键字的下标呢?
	var str="no zuo no die no can no bibi";
	var index=-1;
	while((index=str.indexOf("no",index+1))!=-1){
		console.log("找到了关键字,下标为:"+index);
	}
        输出为:0 7 14 21

6、拼接字符串:

var newStr=str.concat(新字符串,...) //+运算更方便

7、截取字符串:3个

var subStr=str/arr.slice(starti,endi+1);//用法和数组完全一致
	.substring(starti,endi+1);//用法和slice几乎一致,但是不支持负数参数
	.substr(starti,n);//n代表的是截取的个数,不必考虑含头不含尾

8、替换字符串:

var newStr=str.replace("固定关键字"/RegExp,"新内容");
例:
var phone="13983680475";
	var newStr=phone.replace("8368","****");
	console.log(newStr);//139****0475

9、切割/分割/分隔字符串:

作用:将字符串切割为数组:str<==>arr
	var arr=str.split("自定义切割符")
	特殊:
	1、切割后,切割符就不在了
	2、如果你的切割符写的是"",切散每一个字符

10、去掉空白字符:

console.log(str.trim());//去掉前后的空格
console.log(str.trimStart());//去掉前面的空格
console.log(str.trimEnd());//去掉前面的空格