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 ...
随机推荐
- 浏览器打开应用指定的界面-b
iOS中提供了两种在浏览器中打开APP的方法: Smart App Banner 和schema协议,这里介绍schema 在实际开发中我们可能会在浏览器中唤醒我们自己的app,就像手机QQ唤醒快报一 ...
- 领域驱动设计和实践(转:http://kb.cnblogs.com/page/112298/)
引言 软件系统面向对象的设计思想可谓历史悠久,20世纪70年代的Smalltalk可以说是面向对象语言的经典,直到今天我们依然将这门语言视为面向对象语言的基础.随着编程语言和技术的发展,各种语言特性层 ...
- 【无聊放个模板系列】HDU 3068 MANACHER
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #inc ...
- [topcoder]IncrementAndDoubling
http://community.topcoder.com/stat?c=problem_statement&pm=12790&rd=15708 这道题只有两个操作,一是加一,二是数组 ...
- 【Linux安全】安全口令策略设置
命令: vim /etc/login.defs 默认设置: # Password aging controls: # # PASS_MAX_DAYS Maximum number of days a ...
- MySQL学习笔记之一
MySQL装有一个名为mysql的命令行,在提示符下输入mysql将出现如下的简单提示: ➜ ~ mysql Welcome to the MySQL monitor. Commands end wi ...
- SLF4J user manual
http://www.slf4j.org/manual.html The Simple Logging Facade for Java (SLF4J) serves as a simple facad ...
- ruby 编写迭代器
class My def initialize(name,age) @name=name @age=age end def sayName puts @name end def sayAge puts ...
- uml类图的几种关系
UML类图几种关系的总结 在UML类图中,常见的有以下几种关系: 泛化(Generalization), 实现(Realization),关联(Association),聚合(Aggregati ...
- bzoj2738
感人肺腑pascal过不去系列,跪求开O2先不说这个了,学完cdq分治之后又顺手学了一下整体二分感觉这两个东西很多相似的地方,干脆都叫cdq分治好了二分解决k小就是设当前二分的答案为m,把x<= ...