ES6之前的构造函数继承

ES6推出了class类的方法,而这个方法其实可以看成是ES6之前的继承方法整合而成,本质是一个语法糖

这里写一个完整的ES6之前的构造函数继承代码

// 父级构造函数
let ajm = function (name, age) {
    this.name = name;
    this.ajm = ajm;
}
// 父级的原型方法
ajm.prototype.say = function () {
    console.log('我是父构造函数的专属方法');
}
// 实例对象
let aa = new ajm('娃哈哈', 18);
console.log(aa);
aa.say();

// 子级继承父级的两个属性,并且具有自己的专属属性sex
let son = function (name, age, sex) {
    // 将父级的this指向son
    ajm.call(this, name, age);
    this.sex = sex;
}

// 将子级的原型指向父级的实例对象,而不是直接指向父级的原型,这样才能实现修改子级的原型
// 而不动父级的原型
son.prototype = new ajm();
// 再创建一个子级专属方法
son.prototype.Gua = function () {
    console.log('我是子级的专属方法');
     // 在子构造函数中调用父构造函数的方法
     this.say();
}

// 这时子级的原型constructor指向了父级,我们要将它指回子级
son.prototype.constructor = son;
// 子级构造函数实例化
let fs = new son('哎嘿嘿', 20, '男');
console.log(fs);
//子构造函数同时具有父级的方法和属性和自己本身专属的属性
fs.say();
fs.Gua();

// 查看子构造函数的constructor指向,是否指回了子构造函数
console.log(fs.constructor);



值得一提的是,通过现代浏览器的操作属性的便利性,可以改变一个对象的 [[Prototype]] 属性, 这种行为在每一个JavaScript引擎和浏览器中都是一个非常慢且影响性能的操作,使用这种方式来改变和继承属性是对性能影响非常严重的,

并且性能消耗的时间也不是简单的花费在 obj.proto = ... 语句上, 它还会影响到所有继承来自该 [[Prototype]] 的对象,如果你关心性能,你就不应该在一个对象中修改它的 [[Prototype]]。相反, 创建一个新的且可以继承 [[Prototype]] 的对象,推荐使用 Object.create()。

当Object.prototype.proto 已被大多数浏览器厂商所支持的今天,其存在和确切行为仅在ECMAScript 2015规范中被标准化为传统功能,以确保Web浏览器的兼容性。为了更好的支持,建议只使用 Object.getPrototypeOf()

为什么不要直接在Object.prototype上定义方法?

为什么不能改?考虑以下几点:
1、可靠性 当项目只有你一个人时,你想怎么改就怎么改,因为你很清楚他们。当你的项目不止一个人时,就很容易出现冲突,并且你会为了解决这个冲突而花费更多的时间。
举个真实的例子:js红皮书的作者在雅虎工作时,因为同事更改了一个YAHOO.util.Event.stopEvent()方法,结果导致他花了几天的时间去解决这个问题,当好不容易解决了,更多的bug出现了,因为还有很多地方也都依赖于这个方法。所以他说了一句话:Don’t modify objects you don’t own

2、兼容性 不单单是上面的问题,你可能会更关心你的项目是否可以在将来使用。吸取一下Prototype 的教训。

关于prorotype的getElementsByClassName 的故事,大概意思就是说Prototype写了一个很好的方法,后来大家都觉得好,所以JS在原生的方法上也加了这个。但是不幸的是,prototype返回的是Array,JS返回的是NodeList。那在原生方法没出现之前这句代码document.getElementsByClassName('myclass').each(doSomething)
可以好好的执行,但是原生方法出来后,NodeList并没有each方法…所以prototype就悲剧了…

3、如果所有人都改呢?这个问题的严重性应该不用说了…所以用Nicholas C.Zakas的一句话做总结:Don’t modify objects you don’t own。

你可能感兴趣的:(ES6之前的构造函数继承)