1. 闭包:
什么是: 重用并保护一个局部变量的机制
因为,外层函数的作用域无法释放
为什么:
全局变量 局部变量
何时:
希望重用一个变量,又不希望被篡改时
如何使用: 3步:
1. 用外层函数包裹受保护的变量和操作变量的函数
2. 外层函数将内层函数对象返回
3. 使用者,调用外层函数获得返回的内层函数对象。
鄙视:
1. 找受保护的变量
2. 找操作变量函数
3. 同一次外层函数调用返回的所有内层函数对象,共用同一个受保护的局部变量
4. 两次外层函数调用,返回的不同内层函数对象,所操作的变量,没有任何关系。
闭包返回内层函数对象:
1. return
2. 直接给全局变量赋值
3. 将内层函数封装在一个对象中,然后返回对象。
闭包缺点: 占用更多内存空间
且一旦形成闭包,无法自动释放。
正课:
1. *****面向对象
对象: 1.描述现实中一个具体事物的属性和功能的程序结构
事物的属性会成为对象的属性
事物的功能会成为对象的方法
2. 内存中同时存储多个数据和方法的一块存储空间。
面向对象: 在程序中,都是先用对象封装一个事物的属性和功能。然后,再调用对象的方法,来执行任务。
为什么: 符合人日常的习惯。
如何使用: 2步:
1.创建对象——封装: 2个
1.创建一个单独的对象:
1.对象直接量:
var obj={
属性名:属性值,
... : ...,
方法名:function(){...}
}
何时使用:如果创建对象时,已经知道对象的所有属性和方法时。
对象的属性和方法,统称为对象的成员
对象中的每个成员名都是字符串类型
但是,可省略""
问题: 对象的方法中,不能写死对象的属性值
解决: 在对象的方法中,直接访问当前对象自己的属性
this关键词: 专门用在对象的方法中,用来指代正在调用方法的当前对象本身。
其实就是调用方法时,点"."前的对象
总结: 只要在对象的方法中,访问对象自己的属性,必须用this.属性名
2.用new关键词:
var obj=new Object();//创建空对象
={}
obj.属性名=值;
obj.方法名=function(){
...
}
何时使用: 创建对象时,还不知道对象的属性和方法,需要后续动态添加。
*****js中一切对象都是关联数组
相同: 1. 属性名都是字符串,不可重复
2. 随时添加新属性和方法
3. 可用for in遍历
2.批量创建多个相同结构的对象
2步:
1. 定义构造函数:
构造函数:专门定义一类对象统一结构的特殊函数。
为什么: 代码重用
何时使用:今后,只要反复创建多个相同结构的对象前,都要用构造函数先定义统一的结构。
如何定义:
function 类型名/构造函数名(属性参数,..){
//this:当前正在创建的空对象
//向当前空对象中添加新的属性
this.属性名=属性参数;
//向当前空对象中添加新的方法
this.方法名=function(){
...
}
}
2. 用new调用构造函数创建新对象:
var obj=new 构造函数名(属性值);
new: 4件事:
1.创建一个空对象
2.?
3.用新对象调用构造函数
构造函数会向新对象中添加属性很方法。
4.将对象地址返回给obj
2.访问对象的成员:
访问属性: 对象.属性
单个对象属性的用法和变量完全一样
调用方法: 对象.方法(参数)
找到“对象”的“方法”,执行。
单个对象方法的使用和函数完全一样
1.*****面相对象:
封装: 将现实中一个事物的属性和功能集中定义在一个对象中。
如何封装: 2个场景
1. 创建一个单独的对象:
1. 直接量: var obj={
属性名:属性值,
方法名:function(){
...this.属性...
}
}
2. 使用new关键词:
var obj=new Object();
obj.属性名=属性值;
obj.方法名=function(){
...this.属性...
}
补: new和()都可省略,但不可同时省略
new Object()
Object()
new Object
Object
2. 反复创建多个相同结构的对象:
2步:
1. 定义构造函数:
function 构造函数名(属性参数,...){
//this->当前正在创建的空对象
this.属性名=属性参数;
this.方法名=function(){
...this.属性...
}
}
为什么:代码重用
缺: 浪费了内存
2. 用new关键词调用构造函数:
var obj=new 构造函数名(属性值,...)
new: 4件事
1.创建一个空对象
2.设置新对象的__proto__继承构造函数的原型对象。
3.用当前新对象调用构造函数,向对象中添加属性和方法。
4.将新对象地址,返回给变量保存。
解决: 继承:
面向对象三大特点: 封装 继承 多态
继承: 父对象的成员,子对象不必重新创建,就可直接使用。
js中的继承都是用过原型对象实现的
原型和原型链:
原型:保存一类对象,共有成员的父级对象
为什么: 为了实现继承,
优: 代码重用和节约内存
何时使用:只要一类对象共有的成员,都必须集中定义在原型对象中一次即可。
如何使用:
创建: 在定义构造函数时,js会自动创建该类型的原型对象
向原型对象中添加共有成员:
构造函数.prototype.成员名=值
内置对象的原型对象:
解决浏览器的兼容性问题:
如果需要的API,在指定类型的原型对象中不存在,说明不支持
就要在该类型的原型对象中添加所需的共有成员。
其中,在API内部,用this获得当前正再调用API的点前的对象
原型链: 由各级父对象,逐级继承形成的链是结构。
控制着对象成员(属性和方法)的使用顺序:
优先使用对象本地的成员——自有属性
如果本地没有,才延原型链向上查找各级父对象。直到找到为止。——共有属性
如果整个原型链上没有,才返回undefined
判断成员是自有属性,共有属性:
1. 判断自有属性:
var bool=obj.hasOwnProperty("属性名")
判断"属性名"是否是obj的自有属性
保存在obj对象本地。
是自有属性,返回true,否则返回false
2. 判断共有属性:
问题:不是自有属性:
1. 可能在原型链上
2. 也可能根本没有
解决:不是自有,且可以访问到
!obj.hasOwnProperty("属性名")
&&obj.属性名!=undefined
如何修改自有属性和共有属性:
自有属性,只能用所在的对象去修改
共有属性,必须通过原型对象去修改
如果强行使用某个子对象,修改共有属性
后果: 仅在当前子对象添加同名自有属性
导致:当前子对象无法再使用共有属性
删除属性: delete 对象.属性
亲子鉴定:
1.用原型对象检查
var bool=father.isPrototypeOf(child)
判断child是否继承自father
father是否在child的原型链上
如果father在child的原型链上,返回true
否则返回false
2.用构造函数检查
var bool=child instanceof 构造函数
判断child是否是构造函数创建出来的子对象。
补:instance实例:用一个构造函数创建出的一个子对象,就称为子对象是构造函数的实例。
var obj=new 构造函数();
实例化一个"构造函数"类型的对象
var obj=new Array();
var dt=new Date();
多态: 同一个函数,在不同情况下,表现出不同的状态。
重写(override):如果子对象,觉得父对象的成员不好用,就可在子对象本地,重新定义同名成员,来覆盖父对象的成员
call: 强行借用一个本来无法调用到的函数
目标函数.call(obj)
执行时: 相当于obj.目标函数