资讯专栏INFORMATION COLUMN

JavaScript 继承

xcc3641 / 771人阅读

摘要:寄生组合继承称为完美继承其他继承方式都有缺陷以下为种继承的简单写法包括原形链借用构造函数组合继承原形式寄生式寄生组合式种继承父类原形链继承借用构造函数继承组合式继承原形式继承寄生式继承寄生组合式继承以下为种继承的详细写法。

寄生组合继承称为完美继承(其他继承方式都有缺陷)

以下为6种继承的简单写法:
(包括:原形链、借用构造函数、组合继承、原形式、寄生式、寄生组合式6种继承)

//父类
function Parent(name) {
    this.name = name;
}
Parent.prototype.alertHi = function () {
    alert("Hi");
};

//原形链继承
function Child1() {}
Child1.prototype = new Parent();

//借用构造函数继承
function Child2(name) {
    Parent.call(this,name);
}

//组合式继承
function Child3(name) {
    Parent.call(this,name);
}
Child3.prototype = new Parent();
Child3.prototype.constructor = Child3;

//原形式继承
var Child4 = Object.create(Parent);

//寄生式继承
function createChild(child) {
    var clone = Object(child);
    clone.sayHello = function () {
        alert("Hello");
    };
    return clone;
}
var Child5 = createChild(Person);

//寄生组合式继承
var Child6 = function (name) {
    Parent.call(this,name);
};
function inheritPrototype(subType,superType) {
    var prototype = Object(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
}
inheritPrototype(Child6,Parent);

以下为6种继承的详细写法。

原形链继承

//原形链继承
//父类
function Parent() {
    this.flag = true;
}
//父类的原形方法
Parent.prototype.alertFlag = function () {
    alert(this.flag);
};
//子类
function Child() {
    this.flag = false;//修改属性(不写则不修改)
}
//Child 继承 Parent
Child.prototype = new Parent();
//添加原形方法
Child.prototype.sayHello = function () {
    alert("Hello");
};

var child = new Child();
child.alertFlag();//弹出 false
child.sayHello();// 弹出 Hello

//子类修改父类方法
Child.prototype.alertFlag = function () {
    alert(!this.flag);
};
child.alertFlag();//弹出 true

//总结:继承的方法为 Child.prototype = new Parent();(只有一句话)

借用构造函数继承

//借用构造函数继承
function Parent(name) {
    this.name = name;
}
function Child(name,age) {
    Parent.call(this,name);
    this.age = age;
}

//实例
var child = new Child("Andy",28);
alert(child.name);//Andy
alert(child.age);//28

//总结:继承的代码为Parent.call(this,name);(也是一句话),主要解决了this指向的转变和参数的传递。

组合继承

//组合继承
//父类
function Parent(name) {
    this.name = name;
    this.friends = ["Jay","Jolin"];
}
Parent.prototype.sayName = function () {
    alert(this.name);
};

//子类
function Child(name,age) {
    Parent.call(this,name);
    this.age = age;
}
//继承
Child.prototype = new Parent();
//改变constructor指向
Child.prototype.constructor = Child;

//子类添加方法
Child.prototype.sayAge = function () {
    alert(this.age);
};

//创建实例
var c1 = new Child("Andy",29);
var c2 = new Child("Lucy",24);

c1.friends.push("Jack");
c2.friends.push("Coco");

console.log(c1.friends.toString());//Jay,Jolin,Jack
console.log(c2.friends.toString());//Jay,Jolin,Coco

console.log(c1.sayName());//Andy
console.log(c2.sayName());//Lucy

原形式继承

//原形式继承
//实现继承的方法
function obj(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

//但是ECMA5,通过Object.create()方法规范化了原形式继承(即上面的方法)

var person = {
    name:"Andy",
    age:29,
    friends:["Lily","Lucy","Jack"]
};

var Jay = Object.create(person);
Jay.name = "Jay";
Jay.friends.push("Jolin");

var Coco = Object.create(person);
Coco.name = "Coco";
Coco.friends.push("Sunny");

console.log(Jay.name);//Jay
console.log(Coco.name);//Coco
console.log(Jay.friends.toString());//Lily,Lucy,Jack,Jolin,Sunny
console.log(Coco.friends.toString());//Lily,Lucy,Jack,Jolin,Sunny

//没有重写的属性会被共享

var K = Object.create(person);
K.name = "Coco";
K.friends = ["J","Q","A"];

console.log(Jay.friends.toString());//Lily,Lucy,Jack,Jolin,Sunny
console.log(Coco.friends.toString());//Lily,Lucy,Jack,Jolin,Sunny
console.log(K.friends.toString());//J,Q,A

寄生式继承

//寄生式继承

//通过该方法,为子类添加方法,以实现继承;(即增强子类)
function create(child) {
    var clone = Object(child);
    clone.sayHi = function () {
        alert("Hi");
    };
    return clone;
}

var Me = {
    name : "Firefly",
    friends:["Bee","Cicada","Butterfly"]
};
var me = create(Me);

me.sayHi();

寄生组合继承(又称完美继承)

//寄生组合继承
function Parent(a) {
    this.a = a;
}
Parent.prototype = {
    fn:function () {
        alert("Hi");
    }
};
function Child(a,b) {
    Parent.call(this,a);
    this.b = b;
}
//实现继承的方法
function inheritPrototype(subType,superType) {
    var prototype = Object(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
}
//继承
inheritPrototype(Child,Parent);
//为Child添加原型方法
Child.prototype.sayB = function () {
    alert(this.b);
}

注:以下着重介绍组合寄生继承。

例:

function Super(name) {
    this.name = name;
}
Super.prototype = {
    constructor:Super,
    sayName:function () {
        alert(this.name);
    }
    //其他方法...
};
function Sub(name,age){
    Super.call(this,name);
    this.age = age;
}
//实现继承
inheritPrototype(Sub,Super);
//添加原形方法
Sub.prototype.sayAge = function () {
    alert(this.age);
};
//实现继承的方法
function inheritPrototype(subType,superType) {
    var prototype = Object(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
}

//创建实例
var s = new Sub("Andy",28);
//调用方法
s.sayName();
s.sayAge();
//修改属性
s.age = 24;
s.sayAge();
s.name = "Lily";
s.sayName();

实现多继承(修改inheritPrototype()方法)

//父类1
function Super1(name) {
    this.name = name;
}
Super1.prototype = {
    constructor:Super1,
    sayName:function () {
        alert(this.name);
    }
    //其他方法...
};
//父类2
function Super2(gender) {
    this.gender = gender;
}
Super2.prototype = {
    constructor:Super1,
    sayGender:function () {
        alert(this.gender);
    }
    //其他方法...
};
//子类
function Sub(name,gender,age){
    Super1.call(this,name);
    Super2.call(this,gender);
    this.age = age;
}
inheritPrototype(Sub,Super1);
inheritPrototype(Sub,Super2);
//添加原形方法
Sub.prototype.sayAge = function () {
    alert(this.age);
};
//实现继承的方法
function inheritPrototype(subType,superType) {
    var prototype = Object(superType.prototype);
    prototype.constructor = subType;
    //修改的地方
    //subType.prototype = prototype;
    for(par in prototype){
        subType.prototype[par] = prototype[par];
    }
}
//创建实例
var s = new Sub("Andy","man",26);
s.sayName();
s.sayGender();
s.sayAge();

另外,你可以将Super1、Super2和Sub类放在不同的js文件中,在html中引入后调用。

例如:

//将以下代码方法myjs1.js文件中
function Super1(name) {
    this.name = name;
}
Super1.prototype = {
    constructor:Super1,
    sayName:function () {
        alert(this.name);
    }
    //其他方法...
};

//将以下代码放入myjs2.js文件中
function Super2(gender) {
    this.gender = gender;
}
Super2.prototype = {
    constructor:Super1,
    sayGender:function () {
        alert(this.gender);
    }
    //其他方法...
};

//将以下代码放入myjs3.js文件中
function Sub(name,gender,age){
    Super1.call(this,name);
    Super2.call(this,gender);
    this.age = age;
}
inheritPrototype(Sub,Super1);
inheritPrototype(Sub,Super2);
//添加原形方法
Sub.prototype.sayAge = function () {
    alert(this.age);
};
function inheritPrototype(subType,superType) {
    var prototype = Object(superType.prototype);
    prototype.constructor = subType;
    //subType.prototype = prototype;
    for(par in prototype){
        subType.prototype[par] = prototype[par];
    }
}

//在html中引用



Demo:超级玛丽
超级玛丽,有两个属性:name和size,有三个方法:show()、run()和jump();
大的超级玛丽:继承自超级玛丽,在超级玛丽的三个方法基础上修改一个方法:jump();
医生超级玛丽:继承自大的超级玛丽,在大的超级玛丽的三个方法基础上多了一个方法:shot();

超级玛丽类(js1.js):

function SuperMarie(name,size) {
    this.name = name;
    this.size = size;
}
SuperMarie.prototype = {
    constructor:SuperMarie,
    jump:function () {
        console.log(this.name+" jump.");
    },
    run:function () {
        console.log(this.name+" run.");
    },
    show:function () {
        console.log(this.name+""s size is "+this.size);
    }
};

大的超级玛丽类(js2.js):

function BigSuperMarie(name,size) {
    SuperMarie.call(this,name,size);
}
inheritPrototype(BigSuperMarie,SuperMarie);
BigSuperMarie.prototype.jump=function () {
        console.log(this.name+" super jump!");
    };
function inheritPrototype(subType,superType) {
    var prototype = Object(superType.prototype);
    prototype.constructor = subType;
    for(par in prototype){
        subType.prototype[par] = prototype[par];
    }
}

医生超级玛丽类(js3.js):

function DoctorSuperMarie(name,size) {
    BigSuperMarie.call(this,name,size);
}
inheritPrototype(DoctorSuperMarie,BigSuperMarie);
DoctorSuperMarie.prototype.shot = function () {
        console.log(this.name+" shot!");
    };
function inheritPrototype(subType,superType) {
    var prototype = Object(superType.prototype);
    prototype.constructor = subType;
    for(par in prototype){
        subType.prototype[par] = prototype[par];
    }
}

html代码:






文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/90048.html

相关文章

  • 彻底搞懂JavaScript中的继承

    摘要:这正是我们想要的太棒了毫不意外的,这种继承的方式被称为构造函数继承,在中是一种关键的实现的继承方法,相信你已经很好的掌握了。 你应该知道,JavaScript是一门基于原型链的语言,而我们今天的主题 -- 继承就和原型链这一概念息息相关。甚至可以说,所谓的原型链就是一条继承链。有些困惑了吗?接着看下去吧。 一、构造函数,原型属性与实例对象 要搞清楚如何在JavaScript中实现继承,...

    _ivan 评论0 收藏0
  • 讲清楚之 javascript 对象继承

    摘要:中的继承并不是明确规定的,而是通过模仿实现的。继承中的继承又称模拟类继承。将函数抽离到全局对象中,函数内部直接通过作用域链查找函数。这种范式编程是基于作用域链,与前面讲的继承是基于原型链的本质区别是属性查找方式的不同。 这一节梳理对象的继承。 我们主要使用继承来实现代码的抽象和代码的复用,在应用层实现功能的封装。 javascript 的对象继承方式真的是百花齐放,属性继承、原型继承、...

    Jonathan Shieber 评论0 收藏0
  • 讲清楚之 javascript 对象继承

    摘要:中的继承并不是明确规定的,而是通过模仿实现的。继承中的继承又称模拟类继承。将函数抽离到全局对象中,函数内部直接通过作用域链查找函数。这种范式编程是基于作用域链,与前面讲的继承是基于原型链的本质区别是属性查找方式的不同。 这一节梳理对象的继承。 我们主要使用继承来实现代码的抽象和代码的复用,在应用层实现功能的封装。 javascript 的对象继承方式真的是百花齐放,属性继承、原型继承、...

    ruicbAndroid 评论0 收藏0
  • javascript继承 --- 多种继承方式解析(ES5)

    摘要:继承前言作为一门轻量级的脚本语言在和的横空出世之后将其推向的新的高度虽然中出现的新的生成对象的类语法格式但依然为的语法糖而我们依然有必要从的原生实现入手来了解它的继承实现方式给出了更加简洁的固定的类声明方式有兴趣的可以查看阮一峰的入门下面给 javascript继承 前言 javascript作为一门轻量级的脚本语言在ES6和node.js的横空出世之后将其推向的新的高度,虽然 ES6...

    yankeys 评论0 收藏0
  • 白话解释 Javascript 原型继承(prototype inheritance)

    摘要:我们有了构造函数之后,第二步开始使用它构造一个函数。来个例子这种方式很简单也很直接,你在构造函数的原型上定义方法,那么用该构造函数实例化出来的对象都可以通过原型继承链访问到定义在构造函数原型上的方法。 来源: 个人博客 白话解释 Javascript 原型继承(prototype inheritance) 什么是继承? 学过面向对象的同学们是否还记得,老师整天挂在嘴边的面向对象三大特...

    kid143 评论0 收藏0
  • javascript继承你了解多少?

    摘要:和构造函数前面提到,是个内置隐藏属性,虽然在可以通过访问,但是其设计本意是不可被读取和修改的,那么我们如何利用原型链来建立继承关系提供了关键字。到这儿,思路就清晰了,怎么让对象和对象的相连实现继承只需把的构造函数的连接到就行了。 什么是继承? 大多数人使用继承不外乎是为了获得这两点好处,代码的抽象和代码的复用。代码的抽象就不用说了,交通工具和汽车这类的例子数不胜数,在传统的OO语言中(...

    baishancloud 评论0 收藏0

发表评论

0条评论

xcc3641

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<