javascript创建对象、对象继承的实用方式详解


Posted in Javascript onMarch 08, 2016

本文约定:不特殊声明的情况下,属性代指属性或方法。

创建对象、对象继承实际上是一回事:我们所需要的实例对象通过构造函数获得私有属性、通过原型链获得共享的属性。什么是好的方式?私有属性通过构造函数的方式获得(不考虑实例中自定义私有属性)且不需要重写,共享属性通过原型链找到且不需要重复创建。

普适的方式

组合使用构造函数模式和原型模式创建对象

function HNU_student(name) {
  this.name = name;
  this.sayName = function() {
    return this.name;
  };
}
HNU_student.prototype = {
  school: 'HNU',
  saySchool: function() {
    return this.school;
  }
};
Object.defineProperty(HNU_student, 'constructor', {value: HNU_student});

var hiyohoo = new HNU_student('xujian');

通过字面量的方式会重写prototype,且原型的constructor指向了Object,必要的情况下需要重新定义constructor。

寄生组合式继承

function object(o) {
  function F() {};
  F.prototype = o;
  return new F();
}
function inheritPrototype(child, parent) {
  var prototype = object(parent.prototype);
  prototype.constructor = child;
  child.prototype = prototype;
}

function HNU_student(name) {
  this.name = name;
  this.sayName = function() {
    return this.name;
  };
}
HNU_student.prototype.school = 'HNU';
HNU_student.prototype.saySchool = function() {
  return this.school;
};

function Student_2011(name, number) {
  HNU_student.call(this, name);
  this.number = number;
  this.sayNumber = function() {
    return this.number;
  }
}
inheritPrototype(Student_2011, HNU_student);
Student_2011.prototype.graduationTime = 2015;
Student_2011.prototype.sayGraduationTime = function() {
  return this.graduationTime;
};

var hiyohoo = new Student_2011('xujian', 20110803203);

object()的作用:将作为参数传入的对象变成实例的原型,该对象的属性被所有实例共享。

共享属性:inheritPrototype(Student_2011, HNU_student);,子构造函数原型成为超构造函数原型的一个实例,超构造函数原型中的属性共享给子构造函数。
私有属性:HNU_student.call(this, name);,通过子构造函数创建实例时调用超构造函数创建私有属性。

创建对象的其他方式

动态原型模式

function HNU_student(name) {
  this.name = name;
  this.sayName = function() {
    return this.name;
  };

  if (!HNU_student.prototype.school) {
    HNU_student.prototype.school = 'HNU';
    HNU_student.prototype.saySchool = function() {
      return this.school;
    };
  }
}

var hiyohoo = new HNU_student('xujian');

将定义在原型中的共享属性放入构造函数中,使用判断语句,在第一次调用构造函数创建实例时,初始化原型共享属性。

寄生构造函数模式

function SpecialArray() {
  var values = new Array();
  values.push.apply(values, arguments);
  values.toPipedString = function() {
    return this.join('|');
  };

  return values;
}

var colors = new SpecialArray('red', 'black', 'white');

用于为原生构造函数添加特殊的属性。

对象继承的其他方式

组合继承

function HNU_student(name) {
  this.name = name;
  this.sayName = function() {
    return this.name;
  };
}
HNU_student.prototype.school = 'HNU';
HNU_student.prototype.saySchool = function() {
  return this.school;
};
function Student_2011(name, number) {
  HNU_student.call(this, name);
  this.number = number;
  this.sayNumber = function() {
    return this.number;
  };
}
Student_2011.prototype = new HNU_student();
Student_2011.prototype.constructor = Student_2011;
Student_2011.prototype.graduationTime = 2015;
Student_2011.prototype.sayGraduationTime = function() {
  return this.graduationTime;
}
var hiyohoo = new Student_2011('xujian', 20110803203);

共享属性:Student_2011.prototype = new HNU_student();,子构造函数的原型就指向了超构造函数的原型,实例通过原型链找到所有共享的属性。
私有属性:HNU_student.call(this, name);,通过子构造函数创建实例时调用超构造函数创建私有属性。

缺陷:超构造函数被调用了两遍。Student_2011.prototype = new HNU_student();的同时,在子构造函数原型中创建了超构造函数定义的私有属性,这些原型中的私有属性被实例中的同名属性覆盖屏蔽。

原型式继承、寄生式继承

function object(o) {
  function F() {}
  F.prototype = o;
  return new F();
}
var student1 = {
  school: 'HNU',
  saySchool: function() {
    return this.school;
  }
};
var student2 = object(student1);

Object.creat()是ECMAScript5新增的方法,接受两个参数:一是作为原型的原对象,二是重写或新增属性的对象,作用与自定义的object()相同。

var student1 = {
  name: 'xujian',
  school: 'HNU'
};
var student2 = Object.create(student1, {
  name: {
    value: 'huangjing'
  }
});

寄生式继承在原型式继承的基础上添加了额外的属性用来增强对象。

function object(o) {
  function F() {}
  F.prototype = o;
  return new F();
}
function creatAnother(original) {
  var clone = object(original);
  clone.sayHi = function() {
    alert('Hi!');
  };
  return clone;
}
var student1 = {
  school: 'HNU',
  saySchool: function() {
    return this.school;
  }
};
var student2 = creatAnother(student1);

原型式继承和寄生式继承用于创建与已有对象类似的实例对象。

Javascript 相关文章推荐
Javascript下IE与Firefox下的差异兼容写法总结
Jun 18 Javascript
打开新窗口关闭当前页面不弹出关闭提示js代码
Mar 18 Javascript
jQuery实现点击该行即可删除HTML表格行
Oct 17 Javascript
AspNet中使用JQuery上传插件Uploadify详解
May 20 Javascript
微信小程序开发的四十个技术窍门总结(推荐)
Jan 23 Javascript
微信JSAPI Ticket接口签名详解
Jun 28 Javascript
JS实现遍历不规则多维数组的方法
Mar 21 Javascript
vue.js过滤器+ajax实现事件监听及后台php数据交互实例
May 22 Javascript
echarts设置图例颜色和地图底色的方法实例
Aug 01 Javascript
JavaScript原型链与继承操作实例总结
Aug 24 Javascript
JsonServer安装及启动过程图解
Feb 28 Javascript
Node.js中文件系统fs模块的使用及常用接口
Mar 06 Javascript
理解javascript正则表达式
Mar 08 #Javascript
JavaScript实现带播放列表的音乐播放器实例分享
Mar 07 #Javascript
详解JavaScript数组和字符串中去除重复值的方法
Mar 07 #Javascript
JavaScript实现字符串与日期的互相转换及日期的格式化
Mar 07 #Javascript
JavaScript中将数组进行合并的基本方法讲解
Mar 07 #Javascript
Bootstrap每天必学之日期控制
Mar 07 #Javascript
JavaScript过滤字符串中的中文与空格方法汇总
Mar 07 #Javascript
You might like
php中时间轴开发(刚刚、5分钟前、昨天10:23等)
2011/10/03 PHP
深入PHP内存相关的功能特性详解
2013/06/08 PHP
php针对cookie操作的队列操作类实例
2014/12/10 PHP
PHP从FLV文件获取视频预览图的方法
2015/03/12 PHP
PHP封装curl的调用接口及常用函数详解
2018/05/31 PHP
js里的prototype使用示例
2010/11/19 Javascript
jQuery 幻灯片插件(带缩略图功能)
2011/01/24 Javascript
Jquery实现仿新浪微博获取文本框能输入的字数代码
2013/02/22 Javascript
Javascript与jQuery方法的隐藏与显示
2015/01/19 Javascript
浅谈js的url解析函数封装
2016/06/28 Javascript
实例分析浏览器中“JavaScript解析器”的工作原理
2016/12/12 Javascript
js实现按座位号抽奖
2017/04/05 Javascript
angularjs $http实现form表单提交示例
2017/06/09 Javascript
详解vuejs之v-for列表渲染
2017/06/22 Javascript
微信小程序wx.navigateTo方法里的events参数使用详情及场景
2020/01/07 Javascript
JavaScript数组类型Array相关的属性与方法详解
2020/09/08 Javascript
[05:39]2014DOTA2西雅图国际邀请赛 淘汰赛7月14日TOPPLAY
2014/07/14 DOTA
使用scrapy实现爬网站例子和实现网络爬虫(蜘蛛)的步骤
2014/01/23 Python
详解Python中的文件操作
2016/08/28 Python
Python数据类型之String字符串实例详解
2019/05/08 Python
python使用Pandas库提升项目的运行速度过程详解
2019/07/12 Python
利用python实现汉字转拼音的2种方法
2019/08/12 Python
详解使用Python下载文件的几种方法
2019/10/13 Python
python 元组和列表的区别
2020/12/30 Python
CSS3 calc()会计算属性详解
2018/02/27 HTML / CSS
美国时尚配饰品牌:Dooney & Bourke
2017/11/14 全球购物
大整数数相乘的问题
2012/07/22 面试题
酒店管理专业学生求职信
2013/09/27 职场文书
毕业生教师求职信
2013/10/20 职场文书
新闻编辑专业毕业自荐书范文
2014/02/05 职场文书
奉献家乡演讲稿
2014/09/16 职场文书
民间借贷纠纷案件代理词
2015/05/26 职场文书
送给自己的励志语句:要安静的优秀,悄无声息的坚强
2019/11/26 职场文书
如何理解及使用Python闭包
2021/06/01 Python
vue实现书本翻页动画效果实例详解
2022/04/08 Vue.js
Redis基本数据类型List常用操作命令
2022/06/01 Redis