一、创建对象的几种方式

  1、通过字面量创建

var obj = {};

这种写法相当于:

var obj = new Object();

  缺点:使用同一个接口创建很多单个对象,会产生大量重复代码

  2、通过 工厂模式 创建对象 

function createPerson(name, job) {
var o = new Object()
o.name = name
o.job = job
o.sayName = function() {
console.log(this.name)
}
return o
}
var person1 = createPerson('gaosirs', 'teacher')
var person2 = createPerson('X', 'Doctor')

  缺点:工厂模式虽然解决了创建多个相似对象的问题,但没解决对象识别的问题(即怎样知道一个对象的类型)。

  

  3、通过 构造函数 创建对象

function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.sayName=function(){
alert(this.name);
};
} var person1=new Person(...);
var person2=new Person(...);

  缺点:使用构造函数,每个方法都要在每个实例上重新创建一遍。

  4、通过 原型模式 创建对象

function Person() {
}
Person.prototype.name = 'Gaosirs'
Person.prototype.job = 'teacher'
Person.prototype.sayName = function() {
console.log(this.name)
}
var person1 = new Person();
person1.sayName(); //Gaosirs

  更简单的写法:

function Person() {
}
Person.prototype = {
name: 'Gaosirs',
job: 'teacher',
sayName: function() {
console.log(this.name)
}
}
var person1 = new Person()
person1.sayName() // Gaosirs

  缺点: 

  使用原型,所有的属性都将被共享,这是个很大的优点,同样会带来一些缺点

  原型中所有属性实例是被很多实例共享的,这种共享对于函数非常合适。对于那些包含基本值的属性也勉强可以,毕竟实例属性可以屏蔽原型属性。但是引用类型值,就会出现问题了

function Person() {
}
Person.prototype = {
name: 'jiang',
friends: ['Shelby', 'Court']
}
var person1 = new Person()
var person2 = new Person()
person1.friends.push('Van')
console.log(person1.friends) //["Shelby", "Court", "Van"]
console.log(person2.friends) //["Shelby", "Court", "Van"]
console.log(person1.friends === person2.friends) // true

  

  5、组合使用构造函数模式和原型模式 创建对象

  这是使用最为广泛、认同度最高的一种创建自定义类型的方法。它可以解决上面那些模式的缺点

  使用此模式可以让每个实例都会有自己的一份实例属性副本,但同时又共享着对方法的引用

  这样的话,即使实例属性修改引用类型的值,也不会影响其他实例的属性值了

function Person(name) {
this.name = name
this.friends = ['Shelby', 'Court']
}
Person.prototype.sayName = function() {
console.log(this.name)
}
var person1 = new Person()
var person2 = new Person()
person1.friends.push('Van')
console.log(person1.friends) //["Shelby", "Court", "Van"]
console.log(person2.friends) // ["Shelby", "Court"]
console.log(person1.friends === person2.friends) //false

  6、使用 动态原型模式 创建对象

  动态原型模式将所有信息都封装在了构造函数中,初始化的时候,通过检测某个应该存在的方法时候有效,来决定是否需要初始化原型

function Person(name, job) {
// 属性
this.name = name
this.job = job
// 方法
if(typeof this.sayName !== 'function') {
Person.prototype.sayName = function() {
console.log(this.name)
}
}
}
var person1 = new Person('Gaosirs', 'Teacher')
person1.sayName()

  

  只有在sayName方法不存在的时候,才会将它添加到原型中。这段代码只会初次调用构造函数的时候才会执行。

  此后原型已经完成初始化,不需要在做什么修改了

  这里对原型所做的修改,能够立即在所有实例中得到反映

  其次,if语句检查的可以是初始化之后应该存在的任何属性或方法,所以不必用一大堆的if语句检查每一个属性和方法,只要检查一个就行

  7、使用 寄生构造函数模式 创建对象

  这种模式的基本思想就是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新建的对象

function Person(name, job) {
var o = new Object()
o.name = name
o.job = job
o.sayName = function() {
console.log(this.name)
}
return o
}
var person1 = new Person('Gaosirs', 'student')
person1.sayName()

  这个模式,除了使用new操作符并把使用的包装函数叫做构造函数之外,和工厂模式几乎一样

  构造函数如果不返回对象,默认也会返回一个新的对象,通过在构造函数的末尾添加一个return语句,可以重写调用构造函数时返回的值

  8、使用 稳妥构造函数模式 创建对象

  首先明白稳妥对象指的是没有公共属性,而且其方法也不引用this。

  稳妥对象最适合在一些安全环境中(这些环境会禁止使用this和new),或防止数据被其他应用程序改动时使用

  稳妥构造函数模式和寄生模式类似,有两点不同:一是创建对象的实例方法不引用this,而是不使用new操作符调用构造函数

function Person(name, job) {
var o = new Object()
o.name = name
o.job = job
o.sayName = function() {
console.log(name)
}
return o
}
var person1 = Person('Gaosirs', 'student')
person1.sayName()

  变量 person1 中保存的是一个稳妥对象,而除了调用 sayName() 方法外,没有别的办法访问其数据成员。

  和寄生构造函数模式一样,这样创建出来的对象与构造函数之间没有什么关系,instanceof操作符对他们没有意义

  9、使用 Object.create() 方法创建对象

  Object.create() 方法使用现有的对象来提供新创建的对象的__proto__。

const person = {
isHuman: false,
printIntroduction: function () {
console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
}
}; const me = Object.create(person); me.name = "Matthew"; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // inherited properties can be overwritten me.printIntroduction();
  详见:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create
随笔整理自
  https://www.jb51.net/article/117164.htm
 《JavaScript 高级程序设计 第三版 》138页 第六章 面向对象的程序设计
感谢博主分享!

JS 面向对象 ~ 创建对象的 9 种方式的更多相关文章

  1. js中面向对象(创建对象的几种方式)

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

  2. js中创建对象的几种方式

    创建对象指创建一个object并给这个对象添加属性和方法,有以下几个方式: 最基本的: var Person={}; Person.name='tom'; Person.age='20'; Perso ...

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

    1. 对象字面量 var obj={ name:"小小", age:3, car:{ brand:"baoma", } }; } 2.使用内置构造函数 var ...

  4. JS 面向对象 ~ 继承的7种方式

    前言: 继承 是 OO 语言中的一个最为人津津乐道的概念.许多 OO 语言都支持两种继承方式:接口继承 和 实现继承.接口继承只继承方法签名,而实现继承则继承实际的方法.如前所述,由于函数没有签名,在 ...

  5. 【Js】创建对象的6种方式总结、(底部包含属性名为动态的形式)

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

  6. 比较js中创建对象的几种方式

    1.工厂模式 function createObj(name, sex){ var obj = new Object(); obj.name = name; obj.sex = sex; obj.sa ...

  7. js中面向对象(创建对象的几种方式)

    1.面向对象编程(OOP)的特点: 抽象:抓住核心问题 封装:只能通过对象来访问方法 继承:从已有的对象下继承出新的对象 多态:多对象的不同形态 注:本文引用于 http://www.cnblogs. ...

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

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

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

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

随机推荐

  1. 数据库之mysql篇(5)—— 【转载】mysql练习题

    原帖地址:http://www.cnblogs.com/wupeiqi/articles/5748496.html 范例数据sql: /* Navicat Premium Data Transfer ...

  2. Windows Server 2016-WinSer 2016标准版与数据中心版的区别

    今天在整理文章的时候看到有读者问到他现在的测试环境是用的Windows Server 2016标准版,和我现阶段系列文章的环境是否有区别. 其实针对Windows Server 2016 Active ...

  3. Linux系统挂载Windows的共享文件夹

    解决方案 在window上文件设置共享权限 在Linux上在 使用mount 命令挂载 Windows 共享文件夹 实验环境 redhat linux 7操作系统 服务器IP 192.168.100. ...

  4. May 27. 2018 Week 22nd Sunday

    All things come to those who wait. 苍天不负有心人. It is said that those who are patient can see what their ...

  5. 【Linux基础】文件处理实例

    1.文件拆分 //每4000行拆分一个文件 epms_t_ep_fx_stl_xy_20190129.dat 2.行处理 //查找第二列为711611且第三列为711100记录,打印行号和整行数据 a ...

  6. ES5-ES6-ES7_严格模式

    运行模式 正常(混杂)模式与严格模式,除了正常运行模式(混杂模式),ES5添加了第二种运行模式:"严格模式"(strict mode) 顾名思义,这种模式使得Javascript在 ...

  7. OLTP与OLAP的区别

    OLTP和OLAP的区别 联机事务处理OLTP(on-line transaction processing) 主要是执行基本日常的事务处理,比如数据库记录的增删查改.比如在银行的一笔交易记录,就是一 ...

  8. 让你提前认识软件开发(21):C程序中的定时器

    版权声明:本文为博主原创文章.对文章内容有不论什么意见或建议.欢迎与作者单独交流.作者QQ(微信):245924426. https://blog.csdn.net/zhouzxi/article/d ...

  9. RocketMQ事务消息-demo

    RocketMQ为4.3.0版本(我这种写法4.2.0不行) 如果你之前用的其他版本,需要去修改下系统的环境变量 maven工程用到的jar包 <dependencies> <!-- ...

  10. Python *args 和 **kwargs用法

    *args的参数形式把剩下的没有关键字的参数收起来形成一个tuple,*kwargs把有关键字的收起来做成一个字典 def this_fun(a,b,*args,**kwargs): print a ...