理解js对象继承的N种模式


Posted in Javascript onJanuary 25, 2016

本文分享了js对象继承的N种模式,供大家参考。

一、原型链继承

function Person(){};

Person.prototype = {
  constructor: Person,
  name: "Oliver"
};
    
function People(){};

People.prototype = new Person();
People.prototype.constructor = People;
People.prototype.sayName = function(){
  return this.name;
};

var ins = new People();

console.log(ins.sayName());

二、借用构造函数(伪造对象,经典继承)

1、无参数

function SuperType(){
  this.color = ["red","yellow","white"];
}
function SubType(){
  SuperType.call(this);
}

var instance1 = new SubType();
var instance2 = new SubType();

instance1.color.pop();
console.log(instance1.color); //["red", "yellow"]
console.log(instance2.color); //["red", "yellow", "white"]

2、有参数

function SuperType(name){
  this.name = name;
  this.number = [21,32,14,1];
}
function SubType(name,age){
  SuperType.call(this,name);
  this.age = age;
}

var instance1 = new SubType("Oliver",18);
var instance2 = new SubType("Troy",24);

instance2.number.pop();

console.log(instance1.name + instance1.age + instance1.number); //Oliver1821,32,14,1
console.log(instance2.name + instance2.age + instance2.number); //Troy2421,32,14

三、组合继承(伪经典继承)

1、无参数

function SuperType(){
  this.color = ["red","yellow","white"];
}
SuperType.prototype.sayColor = function(){
  return this.color;
};

function SubType(){
  SuperType.call(this);
  this.number = 321;
}
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayNumber = function(){
  return this.number;
};

var instance1 = new SubType();
var instance2 = new SubType();

instance2.color.pop();
console.log(instance1.color + instance1.number); //red,yellow,white321
console.log(instance2.color + instance2.number); //red,yellow321

2、有参数

function SuperType(name){
  this.name = name;
  this.number = [32,1342,11,1];
}
SuperType.prototype.sayName = function(){
  return this.name;
};

function SubType(name,age){
  SuperType.call(this,name);
  this.age = age;
}
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
  return this.age;
};

var instance1 = new SubType("Oliver",18);
var instance2 = new SubType("Troy",24);

instance2.number.pop();
console.log(instance1.sayName() + instance1.sayAge() + instance1.number); //Oliver1832,1342,11,1
console.log(instance2.sayName() + instance2.sayAge() + instance2.number); //Troy2432,1342,11

三、寄生组合式继承(引用类型最理想的范式)

function inheritPrototype(subType,superType){
  var prototype = Object(superType.prototype);
  prototype.constructor = subType;
  subType.prototype = prototype;
}

function SuperType(name){
  this.name = name;
  this.number = [321,321,43];
}
SuperType.prototype.sayName = function(){
  return this.name;
};

function SubType(name,age){
  SuperType.call(this,name);
  this.age = age;
}
inheritPrototype(SubType,SuperType);
SubType.prototype.sayAge = function(){
  return this.age;
};

var instance1 = new SubType("Oliver",18);
var instance2 = new SubType("Troy",24);
instance2.number.pop();

console.log(instance1.sayName() + instance1.sayAge() + instance1.number); //Oliver18321,321,43
console.log(instance2.sayName() + instance2.sayAge() + instance2.number); //Troy24321,321

或者可以把inheritPrototype 函数写成下面这样:

function inheritPrototype(SubType,SuperType){
  SubType.prototype = new SuperType();
  SubType.prototype.constructor = SubType;
}

四、原型式继承(用于共享引用类型的值,与寄生式类似)

1、传统版(先定义object() 函数,再继承)

function object(o){
  function F(){};
  F.prototype = o;
  return new F();
}

var SuperType = {
  name: "Oliver",
  number: [321,321,4532,1]
};

var SubType1 = object(SuperType);
var SubType2 = object(SuperType);

SubType1.name = "Troy";
SubType1.number.pop();

SubType2.name = "Alice";
SubType2.number.pop();

console.log(SubType1.name + SubType2.name + SubType1.number + SubType2.number + SuperType.name + SuperType.number); //TroyAlice321,321321,321Oliver321,321

ECMAScript 5 版(直接用Object.create(),再继承)

var SuperType = {
  name: "Oliver",
  number: [321,321,4532,1]
};

var SubType1 = Object.create(SuperType); //省略了定义object()函数
var SubType2 = Object.create(SuperType);

SubType1.name = "Troy";
SubType1.number.pop();

SubType2.name = "Alice";
SubType2.number.pop();

console.log(SubType1.name + SubType2.name + SubType1.number + SubType2.number + SuperType.name + SuperType.number); //TroyAlice321,321321,321Oliver321,321

ECMAScript 5 简写版(定义Object.create()的第二个参数,再继承)

var SuperType = {
  name: "Oliver",
  number: [321,321,4532,1]
};

var SubType1 = Object.create(SuperType,{
  name: {
    value : "Troy"
  }
});
var SubType2 = Object.create(SuperType,{
  name: {
    value : "Alice"
  }
});

SubType1.number.pop();
SubType2.number.pop();

console.log(SubType1.name + SubType2.name + SubType1.number + SubType2.number + SuperType.name + SuperType.number); //TroyAlice321,321321,321Oliver321,321

寄生式继承(用于共享引用类型的值,与原型式类似)

function createAnother(original){
  var clone = Object(original);
  clone.sayHi = function(){
    return "Hi";
  };
  return clone;
}

var person = {
  name: "Oliver",
  number: [13,21,31,1]
};

var anotherPerson = createAnother(person);
anotherPerson.number.pop();

console.log(anotherPerson.sayHi() + anotherPerson.number); //Hi13,21,31
console.log(person.number); //13,21,31

以上就是本文的全部内容,希望对大家的学习有所帮助。

Javascript 相关文章推荐
jquery.validate分组验证代码
Mar 17 Javascript
iframe父页面获取子页面参数的方法
Feb 21 Javascript
jQuery之DOM对象和jQuery对象的转换与区别分析
Jan 08 Javascript
JS实现网页右侧带动画效果的伸缩窗口代码
Oct 29 Javascript
Jq通过td获取同行其它列td的方法
Oct 05 Javascript
vue + socket.io实现一个简易聊天室示例代码
Mar 06 Javascript
利用js定义一个导航条菜单
Mar 14 Javascript
react学习笔记之state以及setState的使用
Dec 07 Javascript
深入Vue-Router路由嵌套理解
Aug 13 Javascript
使用 webpack 插件自动生成 vue 路由文件的方法
Aug 20 Javascript
用原生JS实现爱奇艺首页导航栏代码实例
Sep 19 Javascript
vue3.0 上手体验
Sep 21 Javascript
解决js函数闭包内存泄露问题的办法
Jan 25 #Javascript
JavaScript数据类型学习笔记
Jan 25 #Javascript
分步解析JavaScript实现tab选项卡自动切换功能
Jan 25 #Javascript
jQuery form 表单验证插件(fieldValue)校验表单
Jan 24 #Javascript
Jquery实现纵向横向菜单
Jan 24 #Javascript
JavaScript、jQuery与Ajax的关系
Jan 24 #Javascript
JavaScript jquery及AJAX小结
Jan 24 #Javascript
You might like
mysql5写入和读出乱码解决
2006/11/25 PHP
浅谈PHP调用Webservice思路及源码分享
2014/06/04 PHP
CodeIgniter启用缓存和清除缓存的方法
2014/06/12 PHP
初识php MVC
2014/09/10 PHP
windows7下php开发环境搭建图文教程
2015/01/06 PHP
laravel 获取某个查询的查询SQL语句方法
2019/10/12 PHP
利用JS重写Cognos右键菜单的实现代码
2010/04/11 Javascript
JavaScript动态修改弹出窗口大小的方法
2015/04/06 Javascript
jQuery Mobile操作HTML5的常用函数总结
2016/05/17 Javascript
详解AngularJS如何实现跨域请求
2016/08/22 Javascript
html5+CSS 实现禁止IOS长按复制粘贴功能
2016/12/28 Javascript
jQuery插件扩展操作入门示例
2017/01/16 Javascript
详解Vue生命周期的示例
2017/03/10 Javascript
angular.js实现购物车功能
2017/10/23 Javascript
详解Webstorm 新建.vue文件支持高亮vue语法和es6语法
2017/10/26 Javascript
浅析JavaScript中的特殊数据类型
2017/12/15 Javascript
[40:55]DOTA2上海特级锦标赛主赛事日 - 2 败者组第二轮#4Newbee VS Fnatic
2016/03/03 DOTA
[01:34]传奇从这开始 2016国际邀请赛中国区预选赛震撼开启
2016/06/26 DOTA
Python中urllib2模块的8个使用细节分享
2015/01/01 Python
python 按照固定长度分割字符串的方法小结
2018/04/30 Python
利用python实现短信和电话提醒功能的例子
2019/08/08 Python
Python datetime包函数简单介绍
2019/08/28 Python
python GUI库图形界面开发之PyQt5信号与槽多窗口数据传递详细使用方法与实例
2020/03/08 Python
python 5个顶级异步框架推荐
2020/09/09 Python
python 第三方库paramiko的常用方式
2021/02/20 Python
HTML5 canvas画图并保存成图片的jcanvas插件
2014/01/17 HTML / CSS
详解使用HTML5 Canvas创建动态粒子网格动画
2016/12/14 HTML / CSS
MATCHESFASHION.COM美国官网:英国奢侈品零售商
2018/10/29 全球购物
成教自我鉴定
2013/10/27 职场文书
护士毕业生自荐信
2014/02/07 职场文书
求职面试个人自我评价
2014/02/28 职场文书
社区服务标语
2014/07/01 职场文书
工商局所长四风自我剖析及整改措施
2014/10/26 职场文书
李强优秀员工观后感
2015/06/16 职场文书
班主任经验交流心得体会
2015/11/02 职场文书
使用 MybatisPlus 连接 SqlServer 数据库解决 OFFSET 分页问题
2022/04/22 SQL Server