可以通过 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. Angular1.x 基础总结

    官方文档:Guide to AngularJS Documentation   w3shools    angularjs教程  wiki   <AngularJS权威教程> Introd ...

  2. 搭建高可用mongodb集群(三)—— 深入副本集内部机制

    在上一篇文章<搭建高可用mongodb集群(二)-- 副本集> 介绍了副本集的配置,这篇文章深入研究一下副本集的内部机制.还是带着副本集的问题来看吧! 副本集故障转移,主节点是如何选举的? ...

  3. RoCE、softRoCE与iWRAP

    RoCE - RDMA over Converged Ethernet 以太网在全球互联的广域网中毫无异议的老大,但在高带宽.低延时的专有网络领域却明显混不开.伴随网络融合概念兴起,IETF发布了DC ...

  4. android去应用市场升级

    private String getAppInfo() {   try {   String pkName = this.getPackageName();   String versionName ...

  5. Python初探-Pycharm,Anaconda-人脸识别

    版权声明:博客版权所有,转载注明出处. https://blog.csdn.net/qq_33083551/article/details/82253026 1.建议先安装Anaconda,再安装Py ...

  6. Redis(二):c#连接Redis

    1.nuget StackExchange.Redis 2.建立RedisHelper类: public class RedisHelper { /// <summary> /// 连接字 ...

  7. Django路由系统---django重点之url映射分发

    django重点之url映射分发 在全局项目的urls.py中进行子项目的映射,然后在子项目中创建一个urls.py去处理自己项目中的请求,同时也实现了代码的解耦 添加路由分发的原则[全局urls.p ...

  8. 编程语言——C----细节

    2017-09-27  18:40:47 程序设计的基本概念 1.计算机语言:把人与计算机之间交流的语言叫做计算机语言 1)计算机语言分为高级语言和低级语言 2)高级语言:远离硬件 3)低级语言:贴近 ...

  9. C# 数据类型转换 显式转型、隐式转型、强制转型

    C# 的类型转换有 显式转型 和 隐式转型 两种方式. 显式转型:有可能引发异常.精确度丢失及其他问题的转换方式.需要使用手段进行转换操作. 隐式转型:不会改变原有数据精确度.引发异常,不会发生任何问 ...

  10. 最优化作业 共轭梯度法 matlab代码

    syms f x1 x2 f=(1/2)*x1^2+x2^2; x=[2;1]; a=[1 0;0 2];% A g1=diff(f,x1); g2=diff(f,x2); g=[g1;g2];%导数 ...