正课:
-
OOP
-
ES5
-
OOP:
自定义继承: -
两种类型间的继承:
问题: 在子类型构造函数中直接调用父类型构造函数,无法将父类型的属性加入到新对象中
原因: 子类型构造函数中直接调用的父类型构造函数,导致父类型构造函数中的this默认指向window,导致父类型的属性都泄漏到全局。
解决: 当一个函数中的this不是想要的时,可用call(),将函数中不想要的this换成想要的对象。
如何: 函数名.call(替换this的对象, 参数值… …)
1. 可立刻调用函数
2. 将函数中的this,临时替换为想要的"对象"
3. 将参数值传给函数
多态:
什么是: 同一个函数,不同情况下表现出不同的状态
包括: 2种:
- 重载:
- 重写(override): 如果子对象觉得从父对象继承来的成员不好用,可在子对象本地定义同名成员,来覆盖父对象的成员。
鄙视: 判断一个对象是不是数组,共有几种方法:
typeof仅能区分原始类型和function,无法进一步区分每种对象的类型
- 判断原型对象:
obj.proto==Array.prototype
Array.prototype.isPrototypeOf(obj) - 判断构造函数:
obj.constructor==Array
obj instanceof Array
obj(是)Array的一个实例吗?
问题: 以上两种方式,检查不严格,可能被篡改 - 判断隐藏的class属性:
Object.prototype.toString.call(obj1)
this->obj1.class - Array.isArray(obj)
直接返回bool值
原理同方法3,也是严格的检查
静态方法:
什么是静态方法: 不需要创建子对象实例,用构造函数就可直接调用的方法
vs 实例方法: 必须创建该类型的子对象,用子对象才能调用的方法
为什么用静态方法: 有时在调用函数时,无法确定调用函数的实例是什么。
何时: 只要希望不确定实例对象,也能调用方法时
如何:
静态方法都要定义在构造函数对象上,而不是添加在原型对象中
鄙视: 何时使用静态方法,何时使用实例方法:
-
如果规定必须某个类型的子对象才能调用的方法,就用实例方法
实例方法保存在该类型的原型对象中 -
如果不确定调用该方法的数据类型时,就用静态方法
静态方法保存在构造函数对象上 -
ES5:
-
严格模式:
什么是: 比普通js运行机制要求更严格的模式
为什么: 解决js中部分广受诟病的缺陷
比如:- 未声明的变量也可赋值,并自动创建在全局——全局污染
- 静默失败: 执行不成功,也不报错
- 普通函数调用中的this默认指window
- 允许递归——效率极低
递归重复计算量巨大!
何时: 今后所有js程序都应该在严格模式下运行
包括:
-
禁止给未声明的变量赋值
-
将静默失败升级为错误
-
普通函数调用中的this不再指向window,而是undefined
-
强烈不建议使用递归
多数递归都可用循环代替
如何: 2种: -
可对整个js文件或
- 保护对象的结构:
什么是: 禁止擅自删除或添加对象的属性
三个层次: - 禁止添加新属性:
Object.preventExtensions(obj)
原理: 每个对象都有一个内部属性: extensible:true
preventExtensions(obj)设置obj的extensible为false - 密封:
在禁止添加新属性的基础上,进一步禁止删除现有属性
Object.seal(obj)
原理: 设置obj的extensible为false
且自动设置obj的每个属性的configurable为false - 冻结:
在密封基础上禁止修改属性值
Object.freeze(obj)
原理: 设置obj的extensible为false
且自动设置obj的每个属性的configurable为false
且自动设置obj的每个属性的writable为false