JS 创建对象的几种方式
面向对象就是把属性和操作属性的方法放在一起作为一个相互依存的整体——对象,即拥有类的概念,基于类可以创建任意多个实例对象,一般具有封装、继承、多态的特性!
ECMA-262把对象定义为:“无序属性的集合,其属性可以包含基本值 对象 或者函数”。这就是说对象是一组没有特定顺序的值,其中值可以是数据或者函数。
虽然Object构造函数或对象字面量都可以创建单个对象,但这些方式有个明显的缺点,那就是使用同一个接口创造很多对象,会产生大量的重复代码。所以产生了下面几种模式。
1 工厂模式
function createPerson(name,age,job){
var o = {};
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
};
return o;
}
var tanya = createPerson("tanya","30","female");
tanya.sayName();
特点:这种模式抽象了创建具体对象的过程。它用函数来封装以特定接口创建对象的细节。
弊端:没有解决对象识别的问题,而且每次生成一个新对象,都要创建新函数sayName,这使得每个对象都有自己的sayName版本,而事实上,所有的对象都共享同一个函数.
2 构造函数模式
function createPerson(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
}
var tanya =new createPerson("tanya","30","female");
tanya.sayName();
PS:构造函数和普通函数的唯一区别就是调用他们的方式不同:任何函数,只要通过new操作符调用就是构造函数,反之就是普通函数。
使用new操作符创建新实例会经历下面4个步骤:
(1) 创建一个新对象
(2) 将构造函数的作用域赋给新对象(就是this指向了这个新对象)
(3) 执行构造函数中的代码(为这个新对象添加属性)
(4) 返回新对象
构造函数和工厂模式的不同之处:
- 没有显示的创建对象
- 直接将属性和方法赋给this对象;
- 没有return语句
构造函数解决了对象识别的问题(tanya有一个constructor属性,该属性指向createPerson),但是就像工厂模式一样,每个方法都会在每个实例中重新创建一遍。我们可以把函数定义转移到构造函数外部来解决这个问题,但是这样就没有封装性可言了。
3 原型模式
首先介绍一下prototype(原型)属性,我们创建的每个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。
PS:JS中万物皆对象,但分为两大类:普通对象和函数对象。所有的函数对象都有一个prototype属性,普通对象是没有prototype属性的,只有_proto_。
function createPerson(){
} createPerson.prototype.name = "tanya";
createPerson.prototype.age = "30";
createPerson.prototype.job = "female";
createPerson.prototype.sayName = function(){
alert(this.name);
};
var tanya =new createPerson();
tanya.sayName();
原型模式虽然解决了构造函数每个方法都会在每个实例中重新创建一遍的问题。但是所有实例在默认情况下都取得了相同的属性值,实例一般都是要有属于自己的全部属性的。
4 组合使用构造函数模式和原型模式
function createPerson(name,age,job){
this.name = name;
this.age = age;
this.job = job;
}
createPerson.prototype.sayName = function(){
alert(this.name);
};
var tanya =new createPerson("tanya","30","female");
tanya.sayName();
这是创建自定义类型的最常见方式,构造函数模式定义实例属性,原型模式定义方法和共享的属性。
5 寄生构造函数模式
function createPerson(name,age,job){
var o = {};
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
};
return o;
}
var tanya =new createPerson("tanya","30","female");
tanya.sayName();
除了使用new操作符来定义新的对象,以及将其称之为构造函数之外,其他和工厂模式定义一模一样。因为创建时用了new,因此使得实现的过程不一样(但是实现过程不重要),结果一样。看起来更优雅
寄生构造函数可以在构造函数不适应的情况使用,比如创建具有额外方法的已有类型(如数组,Date类型等),但是又不污染原有的类型。
6 稳妥构造函数模式
稳妥对象,指的是没有公共属性,其方法也不引用this的对象。
稳妥构造函数与寄生构造函数相似,但是有2点不同:新创建对象的实例方法不引用this,不使用new操作符调用构造函数。
function createPerson(name, age, job) {
var o = new Object(); // private members
var nameUC = name.toUpperCase(); // public members
o.sayName = function() {
alert(name);
};
o.sayNameUC = function() {
alert(nameUC);
}; return o;
} var person = Person("Nicholas", 32, "software Engineer"); person.sayName(); // "Nicholas"
person.sayNameUC(); // "NICHOLAS" alert(person.name); // undefined
alert(person.nameUC); // undefined
凡是想设为 private 的成员都不要挂到 createPerson 返回的对象 o 的属性上面,挂上了就是 public 的了。这里的 private 和 public 都是从形式上类比其他 OO 语言来说的,其实现原理还是 js 中作用域、闭包和对象那一套。
JS 创建对象的几种方式的更多相关文章
- js创建对象的三种方式和js工厂模式创建对象
文章地址: https://www.cnblogs.com/sandraryan/ 创建对象 创建对象的三种方式 构造函数 ,是一种特殊的方法.主要用来在创建对象时初始化对象 1. 调用系统的构造函数 ...
- 第184天:js创建对象的几种方式总结
面向对象编程(OOP)的特点: 抽象:抓住核心问题 封装:只能通过对象来访问方法 继承:从已有的对象下继承出新的对象 多态:多对象的不同形态 一.创建对象的几种方式 javascript 创建对象简单 ...
- js创建对象的三种方式
<script> //创建对象的三种方式 // 1.利用对象字面量(传说中的大括号)创建对象 var obj1 = { uname: 'ash', age: 18, sex: " ...
- js创建对象的几种方式
/** * 顺便重温一下对象的创建方式 * 代码简单说明问题就好 * 概念性的东西这里就不提了,只加上自己简单理解 */ /** * 工厂模式,就是将手动的创建细节封装在一个方法里, * return ...
- JS创建对象的几种方式整理
javascript是一种“基于prototype的面向对象语言“,与java有非常大的区别,无法通过类来创建对象.那么,既然是面象对象的,如何来创建对象呢? 一:通过“字面量”方式创建对象 方法:将 ...
- js创建对象的四种方式
(1)对象字面量 var clock = { hour:12, minute: 10, second: 10, showTime: function(){ alert(this.hou ...
- js创建对象的几种方式 标签: javascript 2016-08-21 15:23 123人阅读 评论(0)
1.传统方法,创建一个对象,然后给这个对象创建属性和方法. var person = new Object(); person.name = "张三"; person.age = ...
- js创建对象的6种方式总结
1.new 操作符 + Object 创建对象 var person = new Object(); person.name = "lisi"; person.age = 21; ...
- js创建对象的6种方式
一.工厂模式 function createStudent(name,age){ var o=new Object(); o.name=name; o.age=age; o.myName=functi ...
随机推荐
- JavaScript跨站脚本攻击
跨站脚本攻击(Cross-Site Scrpting)简称为XSS,指的是向其他域中的页面的DOM注入一段脚本,该域对其他用户可见.恶意用户可能会试图利用这一弱点记录用户的击键或操作行为,以窃取用户的 ...
- DEPRECATED: Use of this script to execute hdfs command is deprecated.
DEPRECATED: Use of this script to execute hdfs command is deprecated. 本人安装的hadoop版本是2.4.0的,但每次执行命令时都 ...
- URAL 1119. Metro(BFS)
点我看题目 题意 : 这个人在左下角,地铁在右上角,由很多格子组成的地图,每一条边都是一条路,每一条边都是100米.还有的可以走对角线,问你从起点到终点最短是多少. 思路 : 其实我想说一下,,,, ...
- 服务器部署_centos 安装nginx手记
前言: a.linux上安装nginx网上有很多文章,本文仅仅是自己整理备忘. b.安装centos的时候,把develop相关组件都装上,免得缺这个缺哪个. c. 本文软件版本:nginx-1.2. ...
- [jobdu]数组中的逆序对
http://ac.jobdu.com/problem.php?pid=1348 数组中的逆序对也是个常见的题目,算法导论中也有一些描述,参考:http://www.cnblogs.com/wuyue ...
- Navicat 导入导出
当我们对mysql数据库进行了误操作,造成某个数据表中的部分数据丢失时,肯定就要利用备份的数据库,对丢失部分的数据进行导出.导入操作了.Navicat工具正好给我们提供了一个数据表的导入导出功能. 1 ...
- 【原创】FPGA开发手记(三) PS/2键盘
以下内容均以Xilinx的Nexys3作为开发板 1.PS/2键盘简介 虽然Nexys3开发板是利用USB接口搭载键盘,但是其原理与PS/2键盘完全相同,现在就仅以PS/2键盘为例讲解如何将键盘搭 ...
- 单元测试中Assert类
一.Assert类的使用 1.Assert类所在的命名空间为Microsoft.VisualStudio.TestTools.UnitTesting 在工程文件中只要引用Microsoft.Visua ...
- 修改NGINX版本名称为任意WEB SERVER
下载好Nginx的安装文件nginx-1.6.0.tar.gz,并把它解压. wget http://nginx.org/download/nginx-1.6.0.tar.gz .tar.gz 然后我 ...
- 使用Action、Func和Lambda表达式
使用Action.Func和Lambda表达式 在.NET在,我们经常使用委托,委托的作用不必多说,在.NET 2.0之前,我们在使用委托之前,得自定义一个委托类型,再使用这个自定义的委托类型定义一个 ...