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之文件操作
Mar 07 Javascript
Javascript 自定义类型方法小结
Mar 02 Javascript
原生javascript实现分享到朋友圈功能 支持ios和android
May 11 Javascript
从零开始学习Node.js系列教程四:多页面实现的数学运算示例
Apr 13 Javascript
在vue项目中引入highcharts图表的方法(详解)
Mar 05 Javascript
前端防止用户重复提交js实现代码示例
Sep 07 Javascript
详解基于Wepy开发小程序插件(推荐)
Aug 01 Javascript
layer.open 子页面弹出层向父页面传输数据的例子
Sep 26 Javascript
js实现旋转的星空效果
Nov 01 Javascript
vant 解决tab切换插件标题样式自定义的问题
Nov 13 Javascript
在vue项目中封装echarts的步骤
Dec 25 Vue.js
JavaScript获取URL参数的方法分享
Apr 07 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
下拉列表多级联动dropDownList示例代码
2013/06/27 PHP
php一行代码获取文件后缀名实例分析
2014/11/12 PHP
PHP Socket网络操作类定义与用法示例
2017/08/30 PHP
同时使用n个window onload加载实例介绍
2013/04/25 Javascript
Javascript无阻塞加载具体方式
2013/06/28 Javascript
MyEclipse取消验证Js的两种方法
2013/11/14 Javascript
推荐5 个常用的JavaScript调试技巧
2015/01/08 Javascript
JS实现新浪博客左侧的Blog管理菜单效果代码
2015/10/22 Javascript
javascript实现计时器的简单方法
2016/02/21 Javascript
Bootstrap模仿起筷首页效果
2016/05/09 Javascript
使用three.js 画渐变的直线
2016/06/05 Javascript
用JS编写一个函数,返回数组中重复出现过的元素(实例)
2017/09/14 Javascript
JavaScript函数绑定用法实例分析
2017/11/14 Javascript
JS实现碰撞检测的方法分析
2018/01/19 Javascript
vue通过路由实现页面刷新的方法
2018/01/25 Javascript
vue项目实战总结篇
2018/02/11 Javascript
vue中使用rem布局代码详解
2019/10/30 Javascript
零基础写python爬虫之爬虫的定义及URL构成
2014/11/04 Python
scrapy自定义pipeline类实现将采集数据保存到mongodb的方法
2015/04/16 Python
解决PyCharm同目录下导入模块会报错的问题
2018/10/13 Python
我用Python抓取了7000 多本电子书案例详解
2019/03/25 Python
TFRecord文件查看包含的所有Features代码
2020/02/17 Python
Python实现我的世界小游戏源代码
2021/03/02 Python
html5 的a标签 Href 拨电话的写法
2013/11/04 HTML / CSS
美国网上订购鲜花:FTD
2016/09/23 全球购物
SmartBuyGlasses意大利:购买太阳镜、眼镜和隐形眼镜
2018/11/20 全球购物
MySQL面试题目集锦
2016/04/14 面试题
汉语专业应届生求职信
2013/10/01 职场文书
行政管理专业推荐信
2013/11/02 职场文书
30年同学聚会邀请函
2014/01/25 职场文书
食品厂厂长岗位职责
2014/01/30 职场文书
物流毕业生个人的自我评价
2014/02/13 职场文书
介绍信的写法
2015/01/31 职场文书
功夫熊猫观后感
2015/06/10 职场文书
通讯稿范文
2015/07/22 职场文书
有关花店创业的计划书模板
2019/08/27 职场文书