理解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对象的代码分享
Nov 02 Javascript
模拟一个类似百度google的模糊搜索下拉列表
Apr 15 Javascript
jQuery时间轴插件使用详解
Jul 16 Javascript
JavaScript位移运算符(无符号) >>> 三个大于号 的使用方法详解
Mar 31 Javascript
js判断登陆用户名及密码是否为空的简单实例
May 16 Javascript
原生javascript 学习之js变量全面了解
Jul 14 Javascript
zTree获取当前节点的下一级子节点数实例
Sep 05 Javascript
vue组件watch属性实例讲解
Nov 07 Javascript
详解React 在服务端渲染的实现
Nov 16 Javascript
Vue Socket.io源码解读
Feb 07 Javascript
vue在App.vue文件中监听路由变化刷新页面操作
Aug 14 Javascript
JS遍历树层级关系实现原理解析
Aug 31 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
人尽可用的Windows技巧小贴士之下篇
2007/03/22 PHP
测试PHP连接MYSQL成功与否的代码
2013/08/16 PHP
php简单计算页面加载时间的方法
2015/06/19 PHP
php项目中类的自动加载实例讲解
2019/09/12 PHP
javaScript 简单验证代码(用户名,密码,邮箱)
2009/09/28 Javascript
jquery下onpropertychange事件的绑定方法
2010/08/01 Javascript
在JavaScript并非所有的一切都是对象
2013/04/11 Javascript
node中socket.io的事件使用详解
2014/12/15 Javascript
jQuery实现鼠标悬停显示提示信息窗口的方法
2015/04/30 Javascript
canvas快速绘制圆形、三角形、矩形、多边形方法介绍
2016/12/29 Javascript
nodejs中request库使用HTTPS代理的方法
2019/04/30 NodeJs
微信小程序基础教程之worker线程的使用方法
2019/07/15 Javascript
JavaScript设计模式之策略模式实现原理详解
2020/05/29 Javascript
[01:08:00]Fnatic vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
python通过邮件服务器端口发送邮件的方法
2015/04/30 Python
Python实战小程序利用matplotlib模块画图代码分享
2017/12/09 Python
运用TensorFlow进行简单实现线性回归、梯度下降示例
2018/03/05 Python
python实战教程之自动扫雷
2018/07/13 Python
Python3从零开始搭建一个语音对话机器人的实现
2019/08/23 Python
使用Python实现牛顿法求极值
2020/02/10 Python
Python flask框架端口失效解决方案
2020/06/04 Python
阿里旅行:飞猪
2017/01/05 全球购物
Aurora London官网:奢华、负担得起的皮革手袋
2020/08/01 全球购物
小区门卫岗位职责
2013/12/31 职场文书
业务副厂长岗位职责
2014/01/03 职场文书
工商管理专业大学生职业生涯规划范文
2014/03/09 职场文书
《搭石》教学反思
2014/04/07 职场文书
个人年终总结范文
2015/03/09 职场文书
2015年秋季学校开学标语
2015/07/16 职场文书
读《工匠精神》有感:热爱工作,精益求精
2019/12/28 职场文书
血轮眼轮回眼特效 html+css
2021/03/31 HTML / CSS
python中subplot大小的设置步骤
2021/06/28 Python
Java 实现限流器处理Rest接口请求详解流程
2021/11/02 Java/Android
豆瓣2021评分最高动画剧集-豆瓣评分最高的动画剧集2021
2022/03/18 日漫
总结三种用 Python 作为小程序后端的方式
2022/05/02 Python
Go gRPC进阶教程gRPC转换HTTP
2022/06/16 Golang