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 相关文章推荐
浅谈EasyUI中Treegrid节点的删除
Mar 01 Javascript
非常实用的12个jquery代码片段
Nov 02 Javascript
利用Node.js制作爬取大众点评的爬虫
Sep 22 Javascript
浅析BootStrap Treeview的简单使用
Oct 12 Javascript
解决JS外部文件中文注释出现乱码问题
Jul 09 Javascript
Angular实现表单验证功能
Nov 13 Javascript
JavaScript页面倒计时功能完整示例
May 15 Javascript
Vue+Vuex实现自动登录的知识点详解
Mar 04 Javascript
详解Vue串联过滤器的使用场景
Apr 30 Javascript
jQuery插件实现图片轮播效果
Oct 19 jQuery
javascript实现搜索筛选功能实例代码
Nov 12 Javascript
在vue中动态修改css其中一个属性值操作
Dec 07 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
Netflix将与CLAMP、乙一以及冲方丁等6名知名制作人合伙展开原创动画计划!
2020/03/06 日漫
php 设计模式之 工厂模式
2008/12/19 PHP
php简单统计中文个数的方法
2016/09/30 PHP
AES加解密在php接口请求过程中的应用示例
2016/10/26 PHP
jquery.boxy弹出框(后隔N秒后自动隐藏/自动跳转)
2013/01/15 Javascript
js中如何把字符串转化为对象、数组示例代码
2013/07/17 Javascript
offsetHeight在OnLoad中获取为0的现象
2013/07/22 Javascript
Javascript控制页面链接在新窗口打开具体方法
2013/08/16 Javascript
jQuery读取和设定KindEditor值的方法
2013/11/22 Javascript
《JavaScript DOM 编程艺术》读书笔记之JavaScript 语法
2015/01/09 Javascript
Dojo获取下拉框的文本和值实例代码
2016/05/27 Javascript
Angularjs 实现分页功能及示例代码
2016/09/14 Javascript
Bootstrap基本模板的使用和理解1
2016/12/14 Javascript
javascript实现非常简单的小数取整功能示例
2017/06/13 Javascript
React中上传图片到七牛的示例代码
2017/10/10 Javascript
Vue多种方法实现表头和首列固定的示例代码
2018/02/02 Javascript
详解express + mock让前后台并行开发
2018/06/06 Javascript
JS数组实现分类统计实例代码
2018/09/30 Javascript
三分钟教你用Node做一个微信哄女友(基友)神器(面向小白)
2019/06/21 Javascript
JavaScript实现Tab选项卡切换
2020/02/13 Javascript
vue实现简易计算器功能
2021/01/20 Vue.js
跟老齐学Python之编写类之二方法
2014/10/11 Python
Python判断变量是否为Json格式的字符串示例
2017/05/03 Python
利用Python yagmail三行代码实现发送邮件
2018/05/11 Python
和孩子一起学习python之变量命名规则
2018/05/27 Python
Python 窗体(tkinter)下拉列表框(Combobox)实例
2020/03/04 Python
python日志通过不同的等级打印不同的颜色(示例代码)
2021/01/13 Python
FirstCry阿联酋儿童和婴儿产品网上购物:FirstCry.ae
2021/02/22 全球购物
自主招生自荐信
2013/12/08 职场文书
遵纪守法演讲稿
2014/05/23 职场文书
三关爱志愿服务活动方案
2014/08/17 职场文书
2014三年级班主任工作总结
2014/12/05 职场文书
小学数学教师研修日志
2015/11/13 职场文书
2016党员干部廉政准则学习心得体会
2016/01/20 职场文书
Python编解码问题及文本文件处理方法详解
2021/06/20 Python
Vue 打包后相对路径的引用问题
2022/06/05 Vue.js