正课:
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.classArray.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