1. 函数:
1.1 定义: 函数是封装的一段可反复执行的代码。
1.2 创建声明:
(1)通过funtion声明:
function func(){
//声明一个函数
}
(2)通过var声明:
var func=funtion(){
//用var声明,这是函数
}
(3)通过new声明:不常用。
var func=new Function('a', 'b', 'var sum=a+b; return sum');
func(1,2) //返回3
1.3 匿名函数: 不需要指定函数名的函数,常用于一次性函数,用完就立刻释放内存,节约空间,避免全局污染。常用于:
(1)回调函数:即一个函数由另一个函数去调用。如:
arr.sort(function(a,b){return a-b;}),
str.replace(reg,function(kw){return 替换值;}),
setInterval(fun,ms) //定时器。
(2)自调函数:自调函数中,即函数自己立刻调用自己,调用后就立刻释放内存。划分临时作用域,避免使用全局变量,避免造成污染,调用后就立刻释放内存。如:
(function(){
//调用后就立刻释放内存
})()
拓展:
垃圾回收: js引擎会自动跟踪对象的引用次数,如果对象不在被任何变量引用,js引擎就自动释放其内存。
垃圾回收器:具有垃圾回收的程序。
主动清理垃圾:将不需要的变量的对象赋值为null。
中文:一个中文至少占据2个字节。
英文:一个英文只占一个字节。
标点符号:一个标点只占一个字节。
1.4 函数作用域: 包括全局作用域,和局部作用域。
(1)全局作用域:一经声明,项目的任何位置都能使用的变量。
(2)局部作用域:在函数体里面声明的变量的作用范围只能在该函数体内使用,在函数体外使用会报错。
1.5 常见的全局函数:
parseInt();
parseFloat();
isNaN();
encodeURI(); //(URI统一资源标识符)作用:对符合统一资源标识符的数据进行编码,并返回编码后的字符串,所谓编码,就是将地址中多字节的文字,编译成单字节的文字。
decodeURI(); //作用与encodeURI()相反,将单字节的内容解析成一个文字。
encodeURIComponent(); //对URI的组件也能进行编码(即允许把特殊符号也进行编码)。
decodeURIComponent(); //对已编码的URI的组件进行解码。
eval(); //执行以字符串方式表示的JS代码(不常用)。
1.6 递归函数: 在一个函数内部再次调用自己。
(1)递归三要素:
① 边界条件:递归前进到达边界条件立刻递归返回。
② 递归前进:
③ 递归返回:
(2)递归效率:在本次调用还未结束时,就开始下一次自己的调用,那么本次调用就会被挂起(扔占据内存),直到所有调用都完成,才会依次返回,所有调用次数越多,效率越低(不常用)。
//1. 递归计算n的阶乘
function f(n){
if(n==1){
return 1;
}else{
return n*f(n-1)
}
}
//2. 递归下的斐波拉契数列第n个值,1.1.2.3.5.8.13.21.34.55.89.....
function fn(n){
if(n==2 || n==2){
return 1
}else{
return f(n-1)+f(n-2)
}
}
2. 对象:
21 定义:描述一个现实中具体事物的属性和功能的程序。
2.2 面向对象:就是程序用对象结构来描述一个具体事物的属性和功能,便于大量数据的管理和维护。
2.3 三大特点:
1).封装:
⑴ 直接量:var obj={属性:值,...,方法(){},...};this.属性名表示对象自己访问自己的属性及方法都必须这样。
⑵ new创建空对象:var obj=new Object();创建空对象,obj.属性名/["属性名"]=值,依次向对象中添加属性及值。
⑶ 构造函数:构造函数,function类型名(){this.属性名=属性参数,...,this.方法名=function(){}};调用自 己的属性,用.属性名/方法名即可。
⑷ Object.create创建:Object.create({})/Object.create(Object.prototype),创建一个空对象,注意:Object.create(null)创建的对象不继承Object的任何方法。
2).继承:父对象的成员,子对象无需创建API就可以直接调用。
1).原型对象;保存同一类型的所有子对象共有方法的父对象。添加:构造函数.prototype.共有方法=值/function(){};
2).自有属性及共有属性;仅当前对象所有的属性为自有属性,保存在原型对象中为所有子对象共有的属性为共有属性。二者都可 以通过子对象.属性名获得其属性值,但是自有属性的修改为子对象.属性名=值,共有属性的的修改为构造函数
的.prototype.共有属性=值;var bool=obj .hasOwnProperty("属性名"),用于判断是否包含指定的自有属性,true为自有属性,false为没有属性或是继承属性。
3).内置对象;内置对象是ES标准中,浏览器厂商已经实现的对象,包Number,String,Boolean(这三个为包装类型),Array, Math,Date,RegExp,Error,Function,Object,Global(Window)共11中内置对象,包装类型指专门封装一个原始类型的值并提供操作原始类型指的API的对 象,内置对象由构造函数和原型对象组成。
4).原型链;由多级父元素逐级继承形成的链式结构。控制着属性和方法的使用顺序,VS作用域链,保存和控制所有的变量的使用顺序。如下图:
5).实例方法与静态方法;
⑴ 修改一个对象的父对象:Object.setPrototypeOf(child,father);
⑵ 修改一类对象的父对象:构造函数.prototype=father;
⑶ 自定义继承:包括定义抽象父类型(父类型构造函数及父类型原型对象)和让子类型继承抽象父类型(子类型原型对象继承父类型原型对象,子类型构造函数借用父类型构造函数)。如下图;
3).多态:重载(如js默认不支持一个函数名执行不同结果,但是函数自带argunment可接收传入参数的类数组)和重写(如原型链上同一个函数,在不同位置具有不同函数)。
拓展:
1. 删除属性:delete只能删除自有属性,不能删除基础属性。
2. 检测判断对象是否有某个属性:
2.1 in检测:'a' in obj ,判断obj对象中是否存在a属性(包括在自有和继承属性中判断)。
2.1 hasOwnProperty检测:obj hasOwnProperty('a')判断obj对象中是否存在a属性(包括在自有和继承属性中判断)。
2.3 !==检测:obj.a !==undefined ,判断obj对象中是否存在a属性(包括在自有和继承属性中判断),但是如obj={a:undefined}这种请求下, !==不能判断该属性是否存在。
3.属性的Object.defineProperty(obj,key,des):修改编辑属性值,vue的响应式原理,就是基于该属性。
Object.defineProperty(obj,'a',{
value:'123',
writable:true,//是否可以修改
set:(newVal)=>{
obj['a']=newVal
},
get:()=>{
return obj['a']
}
})
4.对象的深克隆与浅克隆:
var obj={name:'Ace'}
var newObj=obj //浅克隆,赋值内存地址,修改一个,另一个也会跟着修改
var newObj1=JSON.parse(JSON.stringify(obj)) //深克隆,修改其中一个属性值,不能影响另外一个