面向对象就是把属性和操作属性的方法放在一起作为一个相互依存的整体——对象,即拥有类的概念,基于类可以创建任意多个实例对象,一般具有封装、继承、多态的特性!

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 创建对象的几种方式的更多相关文章

  1. js创建对象的三种方式和js工厂模式创建对象

    文章地址: https://www.cnblogs.com/sandraryan/ 创建对象 创建对象的三种方式 构造函数 ,是一种特殊的方法.主要用来在创建对象时初始化对象 1. 调用系统的构造函数 ...

  2. 第184天:js创建对象的几种方式总结

    面向对象编程(OOP)的特点: 抽象:抓住核心问题 封装:只能通过对象来访问方法 继承:从已有的对象下继承出新的对象 多态:多对象的不同形态 一.创建对象的几种方式 javascript 创建对象简单 ...

  3. js创建对象的三种方式

    <script> //创建对象的三种方式 // 1.利用对象字面量(传说中的大括号)创建对象 var obj1 = { uname: 'ash', age: 18, sex: " ...

  4. js创建对象的几种方式

    /** * 顺便重温一下对象的创建方式 * 代码简单说明问题就好 * 概念性的东西这里就不提了,只加上自己简单理解 */ /** * 工厂模式,就是将手动的创建细节封装在一个方法里, * return ...

  5. JS创建对象的几种方式整理

    javascript是一种“基于prototype的面向对象语言“,与java有非常大的区别,无法通过类来创建对象.那么,既然是面象对象的,如何来创建对象呢? 一:通过“字面量”方式创建对象 方法:将 ...

  6. js创建对象的四种方式

    (1)对象字面量         var clock = { hour:12, minute: 10, second: 10, showTime: function(){ alert(this.hou ...

  7. js创建对象的几种方式 标签: javascript 2016-08-21 15:23 123人阅读 评论(0)

    1.传统方法,创建一个对象,然后给这个对象创建属性和方法. var person = new Object(); person.name = "张三"; person.age = ...

  8. js创建对象的6种方式总结

    1.new 操作符 + Object 创建对象 var person = new Object(); person.name = "lisi"; person.age = 21; ...

  9. js创建对象的6种方式

    一.工厂模式 function createStudent(name,age){ var o=new Object(); o.name=name; o.age=age; o.myName=functi ...

随机推荐

  1. DB天气app冲刺第八天

    ---恢复内容开始--- 今天已经是第八天了冲刺,本来今天的ui设计已经基本成型了,今天下午设计什么的都弄好了,然后自己手贱clean了一下,可能是自己的程序的bug吧,调试没有错误,安装在模拟器上以 ...

  2. sqlserver删除重复数据

    select identity(int,1,1) as autoID, * into #Tmp from [QYTS_QiYeCecdb]select min(autoID) as autoID in ...

  3. android 进度对话框的使用

    import android.app.Activity; import android.app.ProgressDialog; import android.os.Bundle; public cla ...

  4. memcached远程 telnet 无法连接,解决方案

    因为默认的Memcached配置,使用了本机ip:127.0.0.1 ,此时利用VI修改下配置 vi /etc/memcached.conf 文件打开后,修改下,把-l前面加入#号注释掉,重启服务器就 ...

  5. [topcoder]TallPeople

    水题.http://community.topcoder.com/stat?c=problem_statement&pm=2923&rd=5854 一开始错了是因为理解错题意.还有就是 ...

  6. C​+​+​构​造​函​数​,​复​制​构​造​函​数​和​析​构​函​数​专​题

    链接:http://wenku.baidu.com/view/d9316c0e52ea551810a6872a.html 本文作者:黄邦勇帅本文是学习 C++中的最基本的内容,因此学习 C++就应全部 ...

  7. plsql 书写命名规范

    俗话说事不预则废,无规矩不成方圆. 对sql脚本程序的设计,个人认为应该是从编码规范开始. 前段时间公司一些同事提交的脚本,风格迥异,让我审核起来倍感难受,丝毫没有审核代码的快感. 特整理了公司部分常 ...

  8. QQ输入法个人设置

    常用 按键 外观 词库 账户 高级

  9. 转:理解 Linux 的硬链接与软链接

    Linux 的文件与目录 现代操作系统为解决信息能独立于进程之外被长期存储引入了文件,文件作为进程 创建信息的逻辑单元可被多个进程并发使用.在 UNIX 系统中,操作系统为磁盘上的文本与图像.鼠标与键 ...

  10. JSOI2009 游戏

    1443: [JSOI2009]游戏Game Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 557  Solved: 251[Submit][Stat ...