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 相关文章推荐
JQuery 应用 JQuery.groupTable.js
Dec 15 Javascript
javascript smipleChart 简单图标类
Jan 12 Javascript
纯JS实现的批量图片预览加载功能
Aug 14 Javascript
JS中的substring和substr函数的区别说明
May 07 Javascript
jfreechart插件将数据展示成饼状图、柱状图和折线图
Apr 13 Javascript
JavaScript中setUTCFullYear()方法的使用简介
Jun 12 Javascript
解决JavaScript数字精度丢失问题的方法
Dec 03 Javascript
JSON中key动态设置及JSON.parse和JSON.stringify()的区别
Dec 29 Javascript
使用jQuery实现购物车结算功能
Aug 15 jQuery
Vuejs+vue-router打包+Nginx配置的实例
Sep 20 Javascript
详解Vue前端生产环境发布配置实战篇
May 07 Javascript
JS动态显示倒计时效果
Dec 12 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
教你如何快捷的使用cmd访问mysql小技巧
2014/05/26 PHP
php防止sql注入简单分析
2015/03/18 PHP
PHP MPDF中文乱码的解决方式
2015/12/08 PHP
PHP框架性能测试报告
2016/05/08 PHP
微信JSSDK分享功能图文实例详解
2019/04/08 PHP
Javascript在IE和FireFox中的不同表现简析
2012/12/03 Javascript
Js 冒泡事件阻止实现代码
2013/01/27 Javascript
原生js做的手风琴效果的导航菜单
2013/11/08 Javascript
JQuery实现的购物车功能(可以减少或者添加商品并自动计算价格)
2015/01/13 Javascript
JS数组的常见用法实例
2015/02/10 Javascript
jQuery控制元素显示、隐藏、切换、滑动的方法总结
2015/04/16 Javascript
angularjs在ng-repeat中使用ng-model遇到的问题
2016/01/21 Javascript
Webwork 实现文件上传下载代码详解
2016/02/02 Javascript
Bootstarp风格的toggle效果分享
2016/02/23 Javascript
BootStrap iCheck插件全选与获取value值的解决方法
2016/08/24 Javascript
原生js实现ajax方法(超简单)
2016/09/20 Javascript
JavaScript自动点击链接 防止绕过浏览器访问的方法
2017/01/19 Javascript
vue实现微信分享功能
2018/11/28 Javascript
vue项目设置scrollTop不起作用(总结)
2018/12/21 Javascript
Python的collections模块中的OrderedDict有序字典
2016/07/07 Python
python 并发编程 多路复用IO模型详解
2019/08/20 Python
基于Python解密仿射密码
2019/10/21 Python
Python Opencv实现单目标检测的示例代码
2020/09/08 Python
HTML5如何实现元素拖拽
2016/03/11 HTML / CSS
波兰家居饰品和厨房配件网上商店:Maleomi
2020/12/15 全球购物
什么是表空间(tablespace)和系统表空间(System tablespace)
2013/02/25 面试题
自荐信怎么写呢?
2013/12/09 职场文书
2014年大学庆元旦迎新年活动方案
2014/03/09 职场文书
推荐信怎么写
2014/05/09 职场文书
2014年端午节演讲稿范文
2014/05/23 职场文书
奉献家乡演讲稿
2014/09/16 职场文书
解除施工合同协议书
2014/10/17 职场文书
大学生就业意向书
2015/05/11 职场文书
邹越演讲观后感
2015/06/15 职场文书
MySQL CHAR和VARCHAR该如何选择
2021/05/31 MySQL
elementui的el-popover修改样式不生效的解决
2021/06/30 Javascript