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  THIS详解 面向对象
Mar 25 Javascript
JS弹出对话框返回值代码(asp.net后台)
Dec 28 Javascript
js获得网页背景色和字体色的方法
Mar 21 Javascript
jQuery滚动条插件nanoscroller使用指南
Apr 21 Javascript
JScript中的条件注释详解
Apr 24 Javascript
JavaScript实现的背景自动变色代码
Oct 17 Javascript
简单谈谈Javascript中类型的判断
Oct 19 Javascript
JS实现的几个常用算法
Nov 12 Javascript
jquery手机触屏滑动拼音字母城市选择器的实例代码
Dec 11 jQuery
vue父组件异步获取数据传给子组件的方法
Jul 26 Javascript
vue.js编译时给生成的文件增加版本号
Sep 17 Javascript
详细分析Node.js 模块系统
Jun 28 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
thinkPHP中钩子的两种配置调用方法详解
2016/11/11 PHP
YII框架中使用memcache的方法详解
2017/08/02 PHP
用JavaScript将从数据库中读取出来的日期型格式化为想要的类型。
2009/08/15 Javascript
动态加载脚本提升javascript性能
2014/02/24 Javascript
用JavaScript实现用一个DIV来包装文本元素节点
2014/09/09 Javascript
jQuery 实现侧边浮动导航菜单效果
2014/12/26 Javascript
JS遍历ul下的li点击弹出li的索引的实现方法
2016/09/19 Javascript
JS自定义函数对web前端上传的文件进行类型大小判断
2016/10/19 Javascript
vue自定义指令实现v-tap插件
2016/11/03 Javascript
解析NodeJs的调试方法
2016/12/11 NodeJs
JavaScript中英文字符长度统计方法示例【按照中文占2个字符】
2017/01/17 Javascript
Node.JS中事件轮询(Event Loop)的解析
2017/02/25 Javascript
BootStrap表单控件之文本域textarea
2017/05/23 Javascript
js中json对象和字符串的理解及相互转化操作实现方法
2017/09/22 Javascript
nodejs中方法和模块用法示例
2018/12/24 NodeJs
vue-cli 目录结构详细讲解总结
2019/01/15 Javascript
在vue中使用G2图表的示例代码
2019/03/19 Javascript
JavaScript实现简单随机点名器
2019/11/21 Javascript
JavaScript如何判断对象有某属性
2020/07/03 Javascript
vue任意关系组件通信与跨组件监听状态vue-communication
2020/10/18 Javascript
python基于mysql实现的简单队列以及跨进程锁实例详解
2014/07/07 Python
python字符串循环左移
2019/03/08 Python
使用jTopo给Html5 Canva中绘制的元素添加鼠标事件
2014/05/15 HTML / CSS
美国演唱会订票网站:Ticketmaster美国
2017/10/05 全球购物
Coltorti Boutique官网:来自意大利的设计师品牌买手店
2018/11/09 全球购物
架构师岗位职责
2013/11/18 职场文书
证婚人搞笑证婚词
2014/01/10 职场文书
医疗专业毕业生求职信
2014/08/28 职场文书
入党政审材料范文
2014/12/24 职场文书
维稳承诺书
2015/01/20 职场文书
财务出纳岗位职责
2015/03/31 职场文书
2015年小学二年级班主任工作总结
2015/05/21 职场文书
2016年“世界气象日”广播稿
2015/12/17 职场文书
2016廉洁教育心得体会
2016/01/20 职场文书
复制别人的成功真的会成功吗?
2019/10/17 职场文书
JavaScript继承的三种方法实例
2021/05/12 Javascript