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 相关文章推荐
ASP.NET jQuery 实例17 通过使用jQuery validation插件校验ListBox
Feb 03 Javascript
js判断ie版本号的简单实现代码
Mar 05 Javascript
jQuery实现表格颜色交替显示的方法
Mar 09 Javascript
JavaScript实现数字数组按照倒序排列的方法
Apr 06 Javascript
AngularJS基础学习笔记之表达式
May 10 Javascript
js中使用使用原型(prototype)定义方法的好处详解
Jul 04 Javascript
如何解决IONIC页面底部被遮住无法向上滚动问题
Sep 06 Javascript
Angular2 多级注入器详解及实例
Oct 30 Javascript
js读取json文件片段中的数据实例
Mar 09 Javascript
vue.js动态数据绑定学习笔记
May 19 Javascript
Vue列表如何实现滚动到指定位置样式改变效果
May 09 Javascript
vue css 相对路径导入问题级踩坑记录
Jun 05 Vue.js
理解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
PHPExcel简单读取excel文件示例
2016/05/26 PHP
Laravel中间件实现原理详解
2016/10/09 PHP
Yii框架where查询用法实例分析
2019/10/22 PHP
常用简易JavaScript函数
2009/04/09 Javascript
js弹出层之1:JQuery.Boxy (二)
2011/10/06 Javascript
Js 时间间隔计算的函数(间隔天数)
2011/11/15 Javascript
Jquery提交表单 Form.js官方插件介绍
2012/03/01 Javascript
js鼠标滑轮滚动事件绑定的简单实例(兼容主流浏览器)
2014/01/14 Javascript
用C/C++来实现 Node.js 的模块(一)
2014/09/24 Javascript
学习Angularjs分页指令
2016/07/01 Javascript
浅谈jQuery中的checkbox问题
2016/08/10 Javascript
js中字符型和数值型数字的互相转化方法(必看)
2017/04/25 Javascript
jQuery实现全选、反选和不选功能
2017/08/16 jQuery
简述JS控制台的使用
2018/07/15 Javascript
webpack dll打包重复问题优化的解决
2018/10/10 Javascript
JavaScript递归函数定义与用法实例分析
2019/01/24 Javascript
微信小程序在ios下Echarts图表不能滑动的问题解决
2019/07/10 Javascript
vue 实现websocket发送消息并实时接收消息
2019/12/09 Javascript
js实现九宫格布局效果
2020/05/28 Javascript
Vue.js原理分析之nextTick实现详解
2020/09/07 Javascript
Python使用SQLite和Excel操作进行数据分析
2018/01/20 Python
详解django三种文件下载方式
2018/04/06 Python
在Python运行时动态查看进程内部信息的方法
2019/02/22 Python
Python面向对象之继承和多态用法分析
2019/06/08 Python
通过python连接Linux命令行代码实例
2020/02/18 Python
python+gdal+遥感图像拼接(mosaic)的实例
2020/03/10 Python
Python如何使用bokeh包和geojson数据绘制地图
2020/03/21 Python
openCV提取图像中的矩形区域
2020/07/21 Python
美国网上鞋城:Shoeline.com
2016/11/17 全球购物
借款协议书范本
2014/04/22 职场文书
公司会议策划方案
2014/05/17 职场文书
涉密人员保密承诺书
2014/05/28 职场文书
小学班主任培训方案
2014/06/04 职场文书
影视广告专业求职信
2014/09/02 职场文书
给校长的建议书范文
2015/09/14 职场文书
python 进阶学习之python装饰器小结
2021/09/04 Python