理解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实现Meizu魅族官方网站的导航菜单效果
Sep 14 Javascript
javascript中this指向详解
Apr 23 Javascript
移动端横屏的JS代码(beta)
May 16 Javascript
javascript 常用验证函数总结
Jun 28 Javascript
jQuery实现获取元素索引值index的方法
Sep 18 Javascript
vue.js树形组件之删除双击增加分支实例代码
Feb 28 Javascript
Vue监听数据对象变化源码
Mar 09 Javascript
vue实现在表格里,取每行的id的方法
Mar 09 Javascript
Vuex入门到上手教程
Jun 20 Javascript
基于Vue+element-ui 的Table二次封装的实现
Jul 20 Javascript
vue+element的表格实现批量删除功能示例代码
Aug 17 Javascript
JavaScript之Blob对象类型的具体使用方法
Nov 29 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 VS ASP
2006/10/09 PHP
PHP 图片上传实现代码 带详细注释
2010/04/29 PHP
PHP使用Redis长连接的方法详解
2018/02/12 PHP
Laravel框架路由和控制器的绑定操作方法
2018/06/12 PHP
laravel 框架执行流程与原理简单分析
2020/02/01 PHP
JQuery for与each性能比较分析
2013/05/14 Javascript
javascript伸缩菜单栏实现代码分享
2015/11/12 Javascript
JavaScript中值类型和引用类型的区别
2017/02/23 Javascript
vue-router 权限控制的示例代码
2017/09/21 Javascript
jQuery zTree搜索-关键字查询 递归无限层功能实现代码
2018/01/25 jQuery
Vue的事件响应式进度条组件实例详解
2018/02/04 Javascript
从零开始封装自己的自定义Vue组件
2018/10/09 Javascript
微信小程序实现打卡日历功能
2020/09/21 Javascript
JS中的函数与对象的创建方式
2019/05/12 Javascript
深入了解JavaScript 的 WebAssembly
2019/06/15 Javascript
vue中使用element ui的弹窗与echarts之间的问题详解
2019/10/25 Javascript
[37:45]2014 DOTA2国际邀请赛中国区预选赛5.21 DT VS Orenda
2014/05/22 DOTA
Python作用域用法实例详解
2016/03/15 Python
python实现感知器算法详解
2017/12/19 Python
python 删除非空文件夹的实例
2018/04/26 Python
python中in在list和dict中查找效率的对比分析
2018/05/04 Python
python去除文件中重复的行实例
2018/06/29 Python
pycharm编写spark程序,导入pyspark包的3中实现方法
2019/08/02 Python
Python OrderedDict的使用案例解析
2019/10/25 Python
使用Python发现隐藏的wifi
2020/03/04 Python
Python实现查找数据库最接近的数据
2020/06/08 Python
ECHT官方网站:男女健身服
2020/02/14 全球购物
市政施工员自我鉴定
2014/01/15 职场文书
《守株待兔》教学反思
2014/03/01 职场文书
领导干部对照检查材料
2014/08/24 职场文书
法人授权委托书
2014/09/16 职场文书
八一建军节慰问信
2015/02/14 职场文书
城南旧事电影观后感
2015/06/16 职场文书
2016年教师党员创先争优承诺书
2016/03/24 职场文书
高性能跳频抗干扰宽带自组网电台
2022/02/18 无线电
Nginx图片服务器配置之后图片访问404的问题解决
2022/03/21 Servers