可以通过 Object 构造函数或对象字面量的方式创建对象,但是这些方式的缺点是使用同一个接口创建多个对象,会产生大量重复的代码。

1.工厂模式

function createPerson(name, age, job) {
  var o = new Object();
  o.name = name;
  o.age = age;
  o.job = job;
  o.sayName = function () {
    console.log(this.name);
  }
  return o;
}
​
var person1 = createPerson('Nike', 18, 'Student');
console.log(person1.constructor.name) // Object

优点:解决了创建多个相似对象的问题。

缺点:没有解决对象的识别问题(如何知道一个对象的类型)

2.构造函数模式

function Person(name, age, job) {
  this.name = name;
  this.age = age;
  this.job = job;
  this.sayName = function () {
    console.log(this.name);
  }
}
​
var person1 = new Person('Nike', 18, 'Student');
console.log(person1.constructor.name) // Person

优点:可以将构造函数的实例标识为一种特定的类型

缺点:每个方法在每个实例上都要重新创建一次(它们做的事情都一样),如果方法写成全局函数就没有封装性可言了。

3.原型模式

function Person () {}
Person.prototype = {
  constructor: Person,
  name: 'Nike',
  friends: ['阿猫', '阿狗']
}
​
var person1 = new Person();
var person2 = new Person();
​
person1.friends.push('阿黄');
console.log(person1.friends); // ['阿猫', '阿狗', '阿黄']
console.log(person2.friends); // ['阿猫', '阿狗', '阿黄']

缺点

  • 不能用构造函数传递初始化参数,使得所有实例默认情况下取得相同的属性值。

  • 原型中的属性在很多实例中共享,当属性是基本值的时候可以实例上添加一个同名属性隐藏原型中对应的属性,但当属性是引用类型的时候,修改一个实例的属性时是在原型上直接修改的,其它实例的属性也会更着改变。

4.组合使用构造函数和原型模式

function Person(name, age, job) {
  this.name = name;
  this.age = age;
  this.job = job;
  this.friends: ['阿猫', '阿狗']
}
Person.prototype = {
  constructor: Person,
  sayName : function () {
    console.log(this.name);
  }
}
​
var person1 = new Person('Nike', 18, 'Student');
var person2 = new Person('Bob', 22, 'Doctor');
​
person1.friends.push('阿黄');
console.log(person1.friends); // ['阿猫', '阿狗', '阿黄']
console.log(person2.friends); // ['阿猫', '阿狗']

思想:用构造函数模式定义实例属性,原型模式定义方法和共享的属性

优点

  • 每个实例都有自己的一份属性的副本,同时共享着方法的引用,节约内存

  • 支持构造函数传参

5.动态原型模式

function Person(name, age, job) {
  this.name = name;
  this.age = age;
  this.job = job;
  if (typeof this.sayName != 'function') { // 检查初始化之后应该存在的任何属性和方法
    Person.prototype.sayName = function () {
      console.log(this.name)
    }
  }
}
​
var friend = new Person('Nike', 18, 'Student');
friend.sayName();

优点:通过检测某个应该存在的方法在构造函数中初始化原型(必要情况下),即同时使用构造函数和原型

注意:使用动态原型模式是不能使用对象字面量重写原型,因为在已经创建了实例的情况下重写原型会切断现有实例和原型之间的联系。

6.寄生构造函数模式

function Person(name, age, job) {
  var o = new Object();
  o.name = name;
  o.age = age;
  o.job = job;
  o.sayName = function () {
    console.log(this.name);
  }
  return o;
}
​
var friend  = new Person('Nike', 18, 'Student');
friend.sayName(); // Student
​
// ======================================================== //
​
function Sp () {
    var values = new Array();
    values.push.apply(values, arguments);
    values.toPip = function () {
        return this.join("|")
    }
    return values;
}
​
var colors = new Sp('red','blue','pink');
console.log(colors.toPip()) // red|blue|pink

优点:可以在一些特殊情况下为对象创建构造函数

注意:

  • 构造函数没有return的时候,默认会返回新对象实例,有return的时候,可以重写调用构造函数时返回的值。

  • 返回的对象和构造函数或构造函数的原型属性间没有关系。不能用instanceof 确定对象类型

7.稳妥构造函数模式

function Person(name, age, job) {
  var o = new Object();
  o.sayName = function () {
    console.log(name);
  }
  return o;
}
​
var friend  =  Person('Nike', 18, 'Student');
friend.sayName(); // Nike 该属性只能通过 sayName 方法访问

概念:稳妥对象,是指没有公共属性,而且其方法不引用 this 的对象。

优点:安全的环境中(禁止使用 this 或 new),或防止数据被其他应用程序改动

注意:

  • 创建对象的实例方法不引用 this;不使用 new 操作符调用构造函数。

  • 返回的对象和构造函数或构造函数的原型属性间没有关系。不能用instanceof 确定对象类型

javascript 之 对象的更多相关文章

  1. javascript 全局对象--w3school

    JavaScript全局对象 1.  decodeURI()解析某个编码的URI. 2.decodeURInComponent()解析一个编码的URI组件. 3.encodeURI()把字符串编码为U ...

  2. JavaScript Json对象和Json对象字符串的关系 jsonObj<->JsonString

    JavaScript Json对象和Json对象字符串的关系 jsonObj<->JsonString 如下示例: 直接写的a1就是一个Json对象,a2 就是一个Json对象字符串; 通 ...

  3. 从零构建JavaScript的对象系统

    一.正统的类与继承 类是对象的定义,而对象是类的实例(Instance).类不可直接使用,要想使用就必须在内存上生成该类的副本,这个副本就是对象. 以Java为例: public class Grou ...

  4. 关于javascript自定义对象(来自网络)(最近几天不会的)

    javascript定义对象的几种简单方法 1.构造函数方式,全部属性及对象的方法都放在构造方法里面定义 优点:动态的传递参数 缺点:每创建一个对象就会创建相同的方法函数对象,占用大量内存 funct ...

  5. 据说每个大牛、小牛都应该有自己的库——JavaScript原生对象拓展

    在据说每个大牛.小牛都应该有自己的库——框架篇中我扬言要做个小牛,没想到一天没更新,小伙儿伴们就戏谑的问我,油哥是不是要太监了?其实事情是这个样子的,这不是太监的节奏,一是,关于写个自己的库的想法由来 ...

  6. JavaScript RegExp 对象

    JavaScript RegExp 对象 RegExp 对象用于规定在文本中检索的内容. 什么是 RegExp? RegExp 是正则表达式的缩写. 当您检索某个文本时,可以使用一种模式来描述要检索的 ...

  7. JavaScript String 对象

    JavaScript String 对象 String 对象 String 对象用于处理文本(字符串). String 对象创建方法: new String(). 语法 var txt = new S ...

  8. JavaScript Math 对象

    JavaScript Math 对象 Math 对象 Math 对象用于执行数学任务. Math 对象并不像 Date 和 String 那样是对象的类,因此没有构造函数 Math(). 语法 var ...

  9. JavaScript Number 对象

    JavaScript Number 对象 Number 对象 Number 对象是原始数值的包装对象. Number 创建方式 new Number(). 语法 var num = new Numbe ...

  10. JavaScript Array 对象

    JavaScript Array 对象 Array 对象 Array 对象用于在变量中存储多个值: var cars = ["Saab", "Volvo", & ...

随机推荐

  1. 修改maven默认的jdk版本

    修改maven默认的jdk版本,想改彻底需要在maven的全局配文件(settings.xml)增加以下信息:   在profiles 节点下增加: <profile> <id> ...

  2. Java多线程学习笔记(一)

    一 概述 一个进程只有一个至少会运行一个线程,Java中同样存在这样,在调用main方法的时候,线程又JVM所创建. package link.summer7c.test; public class ...

  3. 【Oracle】Update方法

    1.单表更新 update customers set city_name='山西省太原市' where city_name='山西太原' 2.两表(多表)关联update -- 被修改值由另一个表运 ...

  4. Mysql学习---使用Python执行存储过程

    使用Python执行存储过程 使用Python执行存储过程[2部分]: 1.执行存储过程,获取存储过程的结果集  2.将返回值设置给了  @_存储过程名_序号 = #!/usr/bin/env pyt ...

  5. 最近编译tolua_runtime安卓编译错误

    编译时出现以下错误In file included from lj_ffrecord.c:859:0: lj_recdef.h:224:1: error: ‘recff_rawlen’ undecla ...

  6. globalsign代码签名最新步骤

    1.确认gs发的token里边有你的数字证书-需按对方要求步骤提取到 2. 到globalsign.cn上下载数字签名工具:安装后联系支持.要到该工具对应授权文件 3. (如驱动签名)签名工具> ...

  7. 关于eclipse没有js、xml代码提示的解决:下载一个插件

    1)eclipse打开帮助 2)Eclipse Marketplace,然后搜索AngularJS Eclipse 安装后重启就行了 xml的搜索Rinzo. 没有vpn,我的网络到达不了.

  8. 聊聊host中ip/域名映射记录的解析规则

    今天宝叔突然在群里发了个问题; host做如下配置,a.com会指向哪里?或者说ping一下a.com结果会是什么? 127.0.0.1 a.com 192.168.4.106 a.com 192.1 ...

  9. angularJs的工具方法1

    一.angular.bind();   改this指向 <!DOCTYPE HTML> <html ng-app> <head> <meta http-equ ...

  10. CF712D Memory and Scores

    题目分析 实际上两个人轮流取十分鸡肋,可以看作一个人取2t次. 考虑生成函数. 为了方便,我们对取的数向右偏移k位. 取2t次的生成函数为: \[ F(x)=(\sum_{i=0}^{2k}x_i)^ ...