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 相关文章推荐
实现复选框全选/全不选切换
Dec 23 Javascript
js form 验证函数 当前比较流行的错误提示
Jun 23 Javascript
通过身份证号得到出生日期和性别的js代码
Nov 23 Javascript
判断用户是否在线的代码
Mar 05 Javascript
ie6下png图片背景不透明的解决办法使用js实现
Jan 11 Javascript
Javascript保存网页为图片借助于html2canvas库实现
Sep 05 Javascript
JavaScript学习笔记之Cookie对象
Jan 22 Javascript
JavaScript实现MIPS乘法模拟的方法
Apr 17 Javascript
jQuery on()方法绑定动态元素的点击事件实例代码浅析
Jun 16 Javascript
详解在Vue中通过自定义指令获取dom元素
Mar 04 Javascript
详解Angular操作cookies方法
Jun 01 Javascript
nuxt踩坑之Vuex状态树的模块方式使用详解
Sep 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内核介绍及扩展开发指南―基础知识
2011/09/11 PHP
探讨PHP删除文件夹的三种方法
2013/06/09 PHP
php数组添加与删除单元的常用函数实例分析
2015/02/16 PHP
php编写的抽奖程序中奖概率算法
2015/05/14 PHP
简单实现php上传文件功能
2017/09/21 PHP
apache集成php7.3.5的详细步骤
2019/06/20 PHP
php给数组赋值的实例方法
2019/09/26 PHP
javaScript Array(数组)相关方法简述
2009/07/25 Javascript
JavaScript实现简单图片滚动附源码下载
2014/06/17 Javascript
使用typeof判断function是否存在于上下文
2014/08/14 Javascript
jQuery实现滚动条滚动到子元素位置(方便定位)
2017/01/08 Javascript
bootstrap table表格使用方法详解
2017/04/26 Javascript
基于canvas粒子系统的构建详解
2017/08/31 Javascript
jQuery ajax调用webservice注意事项
2017/10/08 jQuery
fetch 使用及如何接收JS传值
2017/11/11 Javascript
JSONP 的原理、理解 与 实例分析
2020/05/16 Javascript
vue接通后端api以及部署到服务器操作
2020/08/13 Javascript
js实现类选择器和name属性选择器的示例步骤
2021/02/07 Javascript
跟老齐学Python之变量和参数
2014/10/10 Python
Python处理PDF及生成多层PDF实例代码
2017/04/24 Python
python编程通过蒙特卡洛法计算定积分详解
2017/12/13 Python
python如何创建TCP服务端和客户端
2018/08/26 Python
Python中一些深不见底的“坑”
2019/06/12 Python
python的pytest框架之命令行参数详解(上)
2019/06/27 Python
Python for循环通过序列索引迭代过程解析
2020/02/07 Python
django中related_name的用法说明
2020/05/20 Python
深入剖析HTML5 内联框架iFrame
2016/05/04 HTML / CSS
ONLY德国官方在线商店:购买时尚女装
2017/09/21 全球购物
Etam艾格英国官网:法国著名女装品牌
2019/04/15 全球购物
什么是方法的重载
2013/06/24 面试题
中层干部竞聘演讲稿
2014/05/15 职场文书
教师师德师风整改措施
2014/10/24 职场文书
感恩母亲节活动总结
2015/02/10 职场文书
党支部工作总结2015
2015/04/01 职场文书
施工员岗位职责范本
2015/04/11 职场文书
Java Socket实现多人聊天系统
2021/07/15 Java/Android