前言 :
在学习 JS 面向对象 的相关知识的时候,对于它怎样去实现的 继承 ?与其他语言相比不同之处又在哪里 ?有哪些需要注重的点 ?它的底层的实现原理又是怎样的 ?这些问题我们会有疑问,在这里总结一下我自己对于它的理解。
- 字面量层面实现继承 ?
完全赋值,实现继承 (对象字面量形式),存在的问题,如果是浅拷贝的话,父类中,要实现 深拷贝,才能达到目的。(采取 递归 的方式)。
var person = { // person 对象,父类
name: 'wuhao',
age: 23,
address: {
home: 'home address',
office: 'office address'
}
}
var programer = { // programer 对象,子类
language: 'javascript'
}
function extend(p, c){ // 浅拷贝不完全继承函数
var c = c || {};
for(var prop in p){
c[prop] = p[prop];
}
}
extend(person, programer); // 调用封装好的继承函数
console.log(programer.name);
console.log(programer.age);
function extendDeeply(p, c){ // 深拷贝完全继承函数
var c = c || {};
for(var prop in p){
if(typeof p[prop] === "object"){
c[prop] = (p[prop].constructor === Array) ? [] : {};
extendDeeply(p[prop],c[prop]);
}else{
c[prop] = p[prop];
}
}
}
extendDeeply(person, programer); // 调用封装好的继承函数
console.log(programer.name);
console.log(programer.age);
- 实现自己的 myCreate() 方法,实现继承 ?(原型链相关知识)
var p = {name:'c'};
function myCreate(p){ // 自己实现Object.create()方法
function F(){};
F.prototype = p;
var ins = new F();
return ins;
}
var o = myCreate(p);
console.log(o.name);
var o1 = Object.create(p); //利用Object.create()方法,实现继承。IE6等版本浏览器不支持。
console.log(o1.name);
- 类层面实现继承 ?
// 创建父类
function P(){}
// 创建子类
function C(){}
// 建立关系
// 1,inherit (有问题,子类暴漏给父类)
C.prototype = P.prototype;
// 2,父类实例作为子类的原型 (存在问题,new P()新建对象,浪费内存。这里只是做原型关系的桥接)
C.prototype = new P();
// 3,中间只是存在空函数
// function F(){};
// F.prototype = P.prototype;
// C.prototype = new F();
C.prototype = Object.create(P.prototype);
var c1 = new C();
- 类层面继承实例 ?
- 书写父类,包括属性和方法。
- 书写子类。
- 实现继承,子类 constructor 修正。
- 给子类添加属性和方法。
// 父类
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.headCount = 1;
Person.prototype.eat = function(){
console.log('eating ...');
}
// 子类
function Pregrammer(name,age,title){
Person.apply(this,arguments)
}
// 继承
// Pregrammer.prototype = Object.create(Person.prototype);
// Pregrammer.prototype.constructor = Pregrammer;
// 自己封装继承函数
createEx(Pregrammer,Person)
function createEx(Child,Parent){
function F(){};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.super = Child.base = Parent.prototype;
}
// 书写子类的属性和方法
Pregrammer.prototype.language = 'javascript';
Pregrammer.prototype.work = function(){
console.log('i am writing code in' + this.language);
// 父类方法,三种方法等价
Parent.prototype.eat();
Pregrammer.super.eat();
Pregrammer.base.eat();
}