理解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 相关文章推荐
javascript的字符串按引用复制和传递,按值来比较介绍与应用
Dec 28 Javascript
jQuery实现点击某个div打开层,点击其他div关闭层实例分析(阻止冒泡)
Nov 18 Javascript
JS实现太极旋转思路分析
Dec 09 Javascript
详解vue 配合vue-resource调用接口获取数据
Jun 22 Javascript
解决在vue项目中,发版之后,背景图片报错,路径不对的问题
Mar 06 Javascript
jquery 动态遍历select 赋值的实例
Sep 12 jQuery
详解vscode中vue代码颜色插件
Oct 11 Javascript
Vue.js组件props数据验证实现详解
Oct 19 Javascript
Vue中常用rules校验规则(实例代码)
Nov 14 Javascript
Node.js API详解之 dns模块用法实例分析
May 15 Javascript
vue使用swiper实现左右滑动切换图片
Oct 16 Javascript
Vant 中的Toast设置全局的延迟时间操作
Nov 04 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
10个实用的PHP代码片段
2011/09/02 PHP
PHP设计模式之结构模式的深入解析
2013/06/13 PHP
php旋转图片90度的方法
2013/11/07 PHP
PHP Curl出现403错误的解决办法
2014/05/29 PHP
php中http与https跨域共享session的解决方法
2014/12/20 PHP
PHP实现自动发送邮件功能代码(qq 邮箱)
2017/08/18 PHP
laravel框架中间件 except 和 only 的用法示例
2019/07/12 PHP
实用javaScript技术-屏蔽类
2006/08/15 Javascript
详解new function(){}和function(){}() 区别分析
2008/03/22 Javascript
js实现拉伸拖动iframe的具体代码
2013/08/03 Javascript
javascript 终止函数执行操作
2014/02/14 Javascript
js delete 用法(删除对象属性及变量)
2014/08/24 Javascript
node.js中的fs.read方法使用说明
2014/12/17 Javascript
jquery实现华丽的可折角广告代码
2015/09/02 Javascript
jQuery实现鼠标经过事件的延时处理效果
2020/08/20 Javascript
BootStrap框架个人总结(bootstrap框架、导航条、下拉菜单、轮播广告carousel、栅格系统布局、标签页tabs、模态框、菜单定位)
2016/12/01 Javascript
win系统下nodejs环境安装配置
2017/05/04 NodeJs
Vue 项目中遇到的跨域问题及解决方法(后台php)
2018/03/28 Javascript
VUE 实现复制内容到剪贴板的两种方法
2019/04/24 Javascript
vue 实现LED数字时钟效果(开箱即用)
2019/12/08 Javascript
js实现搜索提示框效果
2020/09/05 Javascript
Python的动态重新封装的教程
2015/04/11 Python
CentOS 6.X系统下升级Python2.6到Python2.7 的方法
2016/10/12 Python
Python中文件I/O高效操作处理的技巧分享
2017/02/04 Python
Python中字符串格式化str.format的详细介绍
2017/02/17 Python
python3.4用循环往mysql5.7中写数据并输出的实现方法
2017/06/20 Python
python中如何使用正则表达式的非贪婪模式示例
2017/10/09 Python
Python 读取图片文件为矩阵和保存矩阵为图片的方法
2018/04/27 Python
python文件读写代码实例
2019/10/21 Python
python 进程池pool使用详解
2020/10/15 Python
英国最大的独立玩具专卖店:The Entertainer
2019/09/06 全球购物
总经理岗位职责描述
2014/02/08 职场文书
《兰亭集序》教学反思
2014/02/11 职场文书
捐款倡议书怎么写
2014/05/13 职场文书
联村联户简报
2015/07/21 职场文书
《狼牙山五壮士》读后感:宁死不屈,视死如归
2019/08/16 职场文书