2.8深入扩展原型链模式常用的六种继承方式
1. for in 循环遍历的时候,默认的话可以把自己私有的和在它所属类原型上扩展的属性和方法都可以遍历到,但是一般情况下,我们遍历一个对象只需要遍历私有的即可,我们可
以使用以下的判断进行处理即可:
写法一:
Object.prototype.aaa = function(){} var obj = {name:"张三", age: 7} for (var key in obj) { if( obj.propertyIsEnumerable(key) ){ // 遍历可枚举的,把自己在内置类原型上定义的屏蔽掉了 console.log(key) } }
写法二:(比较常用)
for (var key in obj) {
if(obj.hasOwnProperty(key)){// 遍历可枚举的,把自己在内置类原型上定义的屏蔽掉了
console.log(key)
}
}
2.Object.create(proObj) //创建一个新的对象,但是还要把proObj作为这个对象的原型 // 不兼容IE6-8
var obj = { getX: function() {} } var obj2 = Object.create(obj); obj2.getX(); obj.getY = function(){ console.log(2) }
obj2.getY(); //2 此时说明Object.create只是把obj2指向了obj的原型上,所以obj变了,obj2也跟着变了
function object (o) { function Fn () { } Fn.prototype = o; return new Fn; } // Object.create()的原理实现方法
3.1原型继承
#div1.__proto__ ->HTMLDivElement.prototype ->HTMLElement.prototype ->Element.prototype ->Node.prototype -> EventTarget.prototype ->Object.prototype
function MyObject () {} MyObject.prototype = { constructor: Object, hasOwnProperty: function () {}, toString: function () {} } function MyEventTarget () {} MyEventTarget.prototype = new MyObject(); MyEventTarget.prototype.addEventListener = function () {} function MyNode () {} MyNode.prototype = new MyEventTarget; MyNode.prototype.createElement = function () {} var n = new MyNode
原型继承是我们JS中最常用的一种继承方式
子类B想要继承父类A中的所有属性和方法(私有+公有),只需要让B.prototype = new A即可
原型继承的特点:它是把父类中私有的+公有的都继承到了子类原型上(子类公有的)
function A() { this.x = 100 } A.prototype.getX = function () { console.log(this.x) } function B() { this.y = 200 } B.prototype = new A B.prototype.constructor = B; // 否则都指向父类
核心: 原型继承并不是把父类中的属性和方法克隆一份一模一样的给B,而是让B和A之间增加了原型链的连接,以后B的实例n想要A中的getX方法,需要一级级的向上查找来使用
重写:子类的实例,或者子类都可以通过原型链把父类原型的方法给改变了,对父类的其他实例也产生了影响,这就叫做重写
3.2 call继承:把父类私有的属性和方法 克隆一份一模一样的 作为子类私有的属性
function A() { this.x = 100 } A.prototype.getX = function () { console.log(this.x) } function B() { // this->n A.call(this); // A.call(n)把A执行让A中的this变为了n } var n = new B; console.log(n.x)
3.3 冒充对象继承:把父类私有的加公有的克隆一份一模一样的,给子类私有的
function A() { this.x = 100 } A.prototype.getX = function () { console.log(this.x) } function B() { // this ->n var temp = new A; for(var key in temp) { this[key] = temp[key] } temp = null; } var n = new B;
3.4 混合模式继承:原型继承+call继承
function A () { this.x = 100 } A.prototype.getX = function () { console.log(this.x) } function B() { A.call(this) // n.x=100 } B.prototype = new A // B.prptotype: x=100 getX... B.prototype.constructor = B;
3.5 寄生组合式继承:子类的私有继承父类的私有,子类的公有继承父类的公有
function A () { this.x = 100 } A.prototype.getX = function () { console.log(this.x) } function B() { A.call(this) // n.x=100 } B.prototype = Object.create(A.prototype) B.prototype.constructor = B; // 处理兼容 function create (o) { function Fn() {} Fn.prototype = o return new Fn } var n = new B
3.6 中间类继承法 -> 不兼容IE(移动端可以)
function avgFn() {
arguments.__proto__ = Array.prototype
arguments.sort()
arguments.pop()
}