基础
str.charCodeAt() //查看任意字符串的编码
循环
数组
- 创建方式
- 利用new创建
- 利用数组字面量创建数组
一个数组可以元素为任意类型
- 获取元素
索引,[] - 遍历
数组长度是元素个数,不是索引,数组长度自动检测元素 - 修改数组长度:
- 增加数组元素
(1)直接用索引
(2)用数组长度 - 数组与对象
**关联数组:**数组用字符串做下标,可以在数组中能够存储为对象的格式,但是关联数组没有长度,因此遍历要用属性遍历,for k in 数组
数组中可以嵌套对象,有长度
排序
冒泡排序
冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
函数
声明函数
- 利用函数关键字自定义函数(命名函数)
function 函数名(形参1,形参2){
}
调用: 函数名(实参1,实参2); - 函数表达式(匿名函数)
var 变量名=function() {
}
调用: 变量名(实参1,实参2);
形参与实参
函数的形参和实参不匹配的问题
如果实参个数多于形参的个数,会按照形参的个数运算
如果实参的个数小于形参的个数,未被赋值的形参为undefined,函数结果可能为NaN
返回值
function 函数名(形参1,形参2){
return
}
函数通过return将最终结果返回给函数的调用者函数名()
只要函数遇到return就把后面的结果返回给函数的调用者,函数名()=return后的结果
tips:
- return终止执行
- 只能返回一个值,默认为最后的值
- 输出多值时,用数组存放,return数组
- 没有return输出为undefined
arguments的使用
不确定有多少个参数传递时,用arguments来获取,实质上是当前函数的一个内置对象,arguments对象中存储了传递的所有实参
- 展示形式为伪数组,可以进行遍历
- 具有 length属性
- 按索引方式
- 不具有数组的pop,push方法
函数调用
可以互相调用
作用域
就是变量(代码名字)在某个范围内起作用和效果,目的是为了挺高程序的可靠性,减少命名冲突
- 全局作用域
整个script标签 或者是一个JS文件 - 局部作用域(函数作用域)
在函数内部,变量只在函数内部起作用 - 变量的作用域
- 全局变量
对应全局作用域
tips:
在函数内部,没有声明直接赋值的变量也属于全局变量 - 局部变量
对应局部作用域
tips:
函数的形参也可以看作局部变量
- 全局变量
- 从执行效率:
全局变量,只有浏览器关闭时才会销毁,占内存
局部变量,当程序执行完毕后会销毁,节约内存 - ES6有块级作用域
if() /for() {
var num=10;
}
此时,num不能被调用。但在ES5中没有 - 作用域链
根据在内部函数可以访问外部函数变量的机制,用链式查找决定哪些数据能被内部函数访问,采取就近原则
预解析
- JS引擎运行JS分为两步:预解析 代码执行
- 预解析:JS引擎会把JS里面所有的var还有function提升到当前作用域的最前面
- 代码执行:从上往下
- 预解析:变量预解析(变量提升)和 函数预解析(函数提升)
- 变量提升 把所有的变量声明提升到当前的作用域的最前面,不提升赋值操作
- 函数提升 就是把所有的函数声明提升到当前作用域的最前面 不调用函数
结合预解析案例分析看
系统函数
isNaN(),isFinite(),eval()
对象
对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串,数值,数组,函数等。
分三类:自定义对象,内置对象,宿主对象(浏览器端,服务器端)
属性和方法
- 属性:事物的特征,在对象中用属性来表示(常用名词)
- 方法:事物的行为,在对象中用方法来表示(常用动词)
创建对象的三种方式
利用字面量创建对象
var 对象名 = {
键(属性名):值(‘属性值’),
键(属性名):值(‘属性值’),
键(方法名):function(){
}
}
- 里面的属性或者方法采取键值对的形式
- 用逗号隔开
- 方法冒号后面跟匿名函数
调用
- 两种调用对象的属性
- 对象名 . 属性名
- 对象名[‘属性名’]
- 调用对象的方法
- 对象名 . 方法名();
变量、属性、函数、方法的区别
- 变量和属性
- 相同点:用来存储数据
- 不同点
- 函数和方法
- 相同点:实现某种功能
- 不同点
利用new Object创建对象(内置构造函数)
var 对象名 = new Object();
直接添加:
对象名.属性名=属性值;
对象名.属性名=属性值;
对象名.方法名=function(){
};
利用自定义构造函数创建对象
1.因为前面的两种方式一次只能创建一个对象
2. 构造函数里面封装的是对象
3. 构造函数名首字母大写
4. 不需要return
语法
function 构造函数名(参数1,参数2) {
this.属性=值:
this.方法=function(){
}
}
调用
var 新的变量名= new 构造函数名(实参);
构造函数和对象
- 构造函数:泛指的某一个大类
- 对象:特指一个具体的事物
- 利用构造函数创建一个具体对象(实例)的过程叫对象实例化
new关键字
- new 构造函数可以在内存中创建一个空的对象
- this 会指向刚刚创建的空对象
- 执行构造函数里面的代码,给这个空对象添加属性和方法
- 返回这个对象
遍历对象
for(变量 in 对象名) 用于对数组或者对象的属性进行循环操作
- 变量输出 属性名
- 对象名[变量] 输出 属性值
检测是否存在属性
(1).hasOwnProperty(propname);
(2)用.属性名===undefined的返回true的方法
区分同名方法
判断相同名称的方法是否为同一方法:通过判断调用方法的对象的数据类型是否相同,对象类型不同,则方法不同
内置对象
对象分为三种:自定义对象,内置对象||属于ECMAScript, 浏览器对象属于JS
Math对象(非构造函数)
Math 是一个内置对象,它拥有一些数学常数属性和数学函数方法。Math 不是一个函数对象。
Math 用于 Number 类型。它不支持 BigInt
- tips
max/min在数组中使用时的注意点
Math.max(参数1,参数2…) //参数不能是数组的形式
.apply() 方法将数组形式转换为可进行的参数形式 - 常用方法
Math.pow(x,y)求的是x的y次方
- random()随机数方法
- 返回随机小数
- 不加参数
- 想要得到两个数之间的随机整数,并且包含着两个整数
- 想要得到数组的随机元素,长度方法
function getRandomIntInclusive(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值
}
日期对象(构造函数)
- 创建
tips: 创建一个新Date对象的唯一方法是通过new 操作符,若将它作为常规函数调用(即不加 new 操作符),将返回一个字符串,而非 Date 对象。
new Date();
new Date(value);//如果value为数值的话月份会比实际小一个月
new Date(dateString);//字符串形式可以
new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]]);
- 常用方法
如果修改时间,则将get改为set,如setFullYear(),但是不能修改星期,没有setDay()
- 本地字符串格式
不用于实际项目,存在兼容问题
var date = new Date();
date.toLocaleString();
date.toLocaleDateString();
date.toLocaleTimeString();
tips:
- 放参数的时候用2020/11/17,不用-,-苹果可能不兼容
- 求当前时间的函数
var date = new Date();
//2020年11月11日 星期三
function getToDay(){
var year=date.getFullYear();
var month=date.getMonth()+1;//.getMonth()的时间月份是从0开始的,所以比实际小一个月,要+1
var dates=date.getDate();
var arr= ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'];
var day=date.getDay();//.getDay()星期日对应0
var h=date.getHours();
h=h<10?'0'+h:h;
var m=date.getMinutes();
m=m<10?'0'+m:m;
var s=date.getSeconds();
s=s<10?'0'+s:s;
return year+'年'+month+'月'+dates+'日'+' '+arr[day]+h+'时'+m+'分'+s+'秒';
}
console.log(getToDay());
- 获取Date总毫秒数(时间戳)从1970-1-1到现在
//1.
var date = new Date();
console.log(date.valueOf());
console.log(date.getTime());
//2.最常用
var date1 = +new Date(value);//如果没有变量,则获取当前时间;如果有变量则获取,变量时间的总毫秒数
console.log(date1);
//H5新增
console.log(Date.now());
倒计时案例
function countDown(time){
var nowTime = +new Date();
var inputTime= +new Date(time);
var times=(inputTime-nowTime)/1000;
var day=parseInt(times/60/60/24);
var h=parseInt(times/60/60%24);
h=h<10?'0'+h:h;
var m=parseInt(times/60%60);
m=m<10?'0'+m:m;
var s=parseInt(times%60);
s=s<10?'0'+s:s;
return '倒计时:'+day+'天'+h+'时'+m+'分'+s+'秒';
}
console.log(countDown('2020/11/12 00:00:00'));//如果不给具体的时分秒,默认为12:00:00
数组对象(构造函数)
- 用new Array()创建数组对象
var arr=new Array();//一个空数组
var arr=new Array(2);//创建一个长度为2的数组
var arr=new Array(2,3);//等价于[2,3]
- 检测是否为数组
//1.instanceof 运算符,用来检测对象的
var arr=[];
console.log(arr instanceof Array);//》》true
//var obj={};
//console.log(obj instanceof Object);//》》true
//2.Array.isArray() H5新增方法
console.log(Array.isArray(arr));
- 添加删除数组元素的方法
- 数组排序
//1.翻转数组
//.reverse()方法,影响原数组
var arr=[11,5,4,6,12,33,45,88];
arr.reverse();
//2.数组排序
arr.sort(function (a,b) {
return a-b; //升序排序,从小到大,冒泡
//return b-a; //降序排序
});
- 获取索引
.indexOf(要查找的元素,[起始的位置])
var arr=[11,5,4,6,12,33,11,45,88];
var index=arr.indexOf(11);//》》0,只返回前面第一个满足条件的索引
var lastIndex =arr.lastIndexOf(11);//从后面找,但索引号不变
//如果不存在则会返回-1
var OtherIndex=arr.indexOf(11,1);//从索引为1的元素开始查找
去重案例
思路(核心算法):
- 遍历旧数组,每一个元素和去查询新数组,没有则将其放入,否则不添加
- 判断是否存在:用索引号,indexOf(旧数组的元素),如果不存在则会返回-1
function unique(arr) {
var newArr=[];
for(var i=0;i<arr.length;i++){
if(newArr.indexOf(arr[i])==-1){
newArr[newArr.length]=arr[i];//或者newArr.push(arr[i]);
}
}
return newArr;
}
var arr=['c','a','z','a','x','a','x','c','b'];
unique(arr);
- 数组转换为字符串
//1.toString()
var arr=[1,2,3];
console.log(arr.toString());//》》1,2,3
//2.join(分隔符)
console.log(arr.join('-'));//》》1-2-3
- 其他数组方法
splice(起始位置,删除数量,删除后插入的元素),删除数量为空时,默认删除到最后
字符串对象(构造函数)
-
字符串的不可变性
不管是拼接,还是重新赋值,指的是里面的值不变,变得是内存地址,开辟了一个新的内存空间 -
常用转义字符
-
根据字符返回位置
indexOf方法
查找字符串中重复出现的位置与次数案例
思路:
核心算法:
(1)先查找第一个所要找的字符的位置
(2)只要返回结果不为-1,就继续往后查找
(3)重复的查找利用第二个参数,将当前索引加1,从而继续查找
var str='abcoefoxyozzopp';
function indexSearch(n){
var count=0;
var i=str.indexOf(n);
while(i!=-1){
console.log(i);
count++;
i=str.indexOf(n,i+1);
}
return count;
}
- 根据位置返回字符(重点)
统计字符串中出现最多的字符案例
思路:
核心算法:
(1)利用charAt()遍历字符
(2)把每个字符都存储给对象,如果对象没有该属性就为1,有则+1
(3)遍历对象,得到最大值和该字符
function countCharMax(str){
//方法1
var obj={//每一个字符都赋值为0,用来方便统计
a:0,b:0,c:0,d:0,e:0,f:0,g:0,h:0,i:0,g:0,k:0,l:0,m:0,n:0,o:0,p:0,q:0,r:0,s:0,t:0,u:0,v:0,w:0,x:0,y:0,z:0
};
for(var i=0;i<str.length;i++){
if(obj.hasOwnProperty(str.charAt(i))){//判断属性是否存在,存在则累加
obj[str.charAt(i)]++;
}
}
//方法2
// var obj={};
// for(var i=0;i<str.length;i++){
// if(obj[str.charAt(i)]){
// obj[str.charAt(i)]++;
// }else{
// obj[str.charAt(i)]=1;
// }
// }
var max=0;
var ch='';
for(var k in obj){
if(obj[k]>max){
max=obj[k];//把属性值取出来
ch=k;//把这个属性取出来
}
}
return '最多出现的字符是:'+ch+',出现了'+max+'次';
}
- 字符串操作方法(重点)
- replace(str1,str2) ;把str1替换成str2,只会替换第一个字符,不影响原字符串
- split(‘分隔符’)字符串转换为数组,分隔符和字符串的分隔符对应
- toUpperCase() 转换大写
- toLowerCase() 转换小写
数值对象(构造函数)
Number.toFixed() 保留几位小数
var num=new Number();
num=12;
num=num.toFixed(2);
布尔对象
5个false:0 NaN undefined ‘’ null(隐式转换布尔型)
数据类型
简单类型(基本数据类型)与复杂类型(引用类型)
- 简单类型: 值类型/基本类型,在变量存储的是值本身,返回的是值本身
- str,number,boolean,undefined,null(返回的是空对象object)
- 复杂类型: 引用类型,在存储时变量中存储的仅仅是地址(引用),有 属性 和 方法
- 数组、通过new关键字创建的对象(系统对象,自定义对象)如Object、Array、Date等
- 基本包装类型: 把简单数据类型包装为复杂数据类型,使基本数据类型可以用关于属性和方法
- JS提供三个特殊引用类型:String,Number,Boolean
过程:
- JS提供三个特殊引用类型:String,Number,Boolean
//(1)把简单数据类型通过new对象的方法包装成复杂数据类型
var temp=new String();
//(2)把临时变量给str
str =temp;
//(3)销毁临时变量
temp=null;
栈和堆
- 栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;简单类型存放到栈
- 堆(操作系统):由程序员分配释放内存,若不释放,由垃圾回收及回收;存储复杂类型
- 堆内存:实际上指的就是优先队列的一种数据结构,第1个元素有最高的优先权;
- 栈内存:实际上就是满足先进后出的性质的数学或数据结构。
- 栈内存是存取速度比堆要快,仅次于寄存器,栈数据可以共享。
简单类型传参
复杂类型传参
在执行f1函数后,person对象的name变为张学友
深拷贝和浅拷贝
ES6简
- 块级作用域
(1)用let声明的变量不存在变量的提升,let在全局作用域下创建的变量也不是全局变量
(2)同一作用域下,不允许重复声明
(3)格式:{}之间就是一个块级作用域下,例如if、else、for、while都是一个块级作用域 - 函数增强
(1) 给参数设置默认值
function add(a,b,c) {
console.log(a+b+c);
}
add(8000,3000);//>>输出NaN
function add2(a,b,c=0) {
console.log(a+b+c);
}
add2(8000,3000);//>>输出11000
(2)箭头函数
简化了匿名函数,比匿名函数功能多
let substract= function (a,b) {
return a-b;
}
//箭头函数
let substract= (a,b)=>{
return a-b;
};
//如果箭头函数的函数体只有一行return形式时,可以直接写公式
let substract= (a,b)=>a-b;
(3)模板字符串
`模板字符串:${JS公式/获取的数据}`(可以回车换行)