理解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 相关文章推荐
node.js中的events.EventEmitter.listenerCount方法使用说明
Dec 08 Javascript
js实现顶部可折叠的菜单工具栏效果实例
May 09 Javascript
谷歌showModalDialog()方法不兼容出现对话窗口的解决办法
Feb 15 Javascript
浅谈addEventListener和attachEvent的区别
Jul 14 Javascript
利用JS判断字符串是否含有数字与特殊字符的方法小结
Nov 25 Javascript
jQuery实现删除li节点的方法
Dec 06 Javascript
适用于手机端的jQuery图片滑块动画
Dec 09 Javascript
JavaScript数据结构中串的表示与应用实例
Apr 12 Javascript
微信小程序 Buffer缓冲区的详解
Jul 06 Javascript
浅谈Koa2框架利用CORS完成跨域ajax请求
Mar 06 Javascript
详解vue中axios的封装
Jul 18 Javascript
javascript面向对象三大特征之封装实例详解
Jul 24 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
支持中文的php加密解密类代码
2011/11/27 PHP
php提示无法加载或mcrypt没有找到 PHP 扩展 mbstring解决办法
2012/03/27 PHP
文件上传之SWFUpload插件(代码)
2015/07/30 PHP
php四种定界符详解
2017/02/16 PHP
php脚本守护进程原理与实现方法详解
2017/07/20 PHP
PHP实现基本留言板功能原理与步骤详解
2020/03/26 PHP
jquery的ajax从纯真网(cz88.net)获取IP地址对应地区名
2009/12/02 Javascript
JavaScript性能陷阱小结(附实例说明)
2010/12/28 Javascript
jQuery为iframe的body添加click事件的实现代码
2011/04/07 Javascript
JQuery动画和停止动画实例代码
2013/03/01 Javascript
js点击事件链接的问题解决
2014/04/25 Javascript
浅谈页面装载js及性能分析方法
2014/12/09 Javascript
jQuery实现Div拖动+键盘控制综合效果的方法
2015/03/10 Javascript
jquery实现仿Flash的横向滑动菜单效果代码
2015/09/17 Javascript
JavaScript实现阿拉伯数字和中文数字互相转换
2016/06/12 Javascript
使用jQuery ajaxupload插件实现无刷新上传文件
2017/04/23 jQuery
基于jquery实现多选下拉列表
2017/08/02 jQuery
ES6解构赋值的功能与用途实例分析
2017/10/31 Javascript
javascript实现简易聊天室
2019/07/12 Javascript
Python模块学习 re 正则表达式
2011/05/19 Python
python使用PyCharm进行远程开发和调试
2017/11/02 Python
Tensorflow 同时载入多个模型的实例讲解
2018/07/27 Python
Python使用sklearn实现的各种回归算法示例
2019/07/04 Python
python各层级目录下import方法代码实例
2020/01/20 Python
selenium3.0+python之环境搭建的方法步骤
2021/02/01 Python
CSS3 Columns分列式布局方法简介
2014/05/03 HTML / CSS
澳大利亚优惠网站:Deals.com.au
2019/07/02 全球购物
英国领先的游戏零售商:GAME
2019/09/24 全球购物
新员工培训个人的自我评价
2013/10/09 职场文书
班级体育活动总结
2014/07/05 职场文书
抢劫罪辩护词
2015/05/21 职场文书
大学生安全教育主题班会
2015/08/12 职场文书
小区物业管理2015年度工作总结
2015/10/22 职场文书
一个家长教育孩子的心得体会
2016/01/15 职场文书
关于@OnetoMany关系映射的排序问题,使用注解@OrderBy
2021/12/06 Java/Android
golang为什么要统一错误处理
2022/04/03 Golang