博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javascript创建对象的几种方式
阅读量:7066 次
发布时间:2019-06-28

本文共 2878 字,大约阅读时间需要 9 分钟。

注: 第4种模式是最常用的模式。

1.工厂模式

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('Jiang', 'student')var person2 = createPerson('X', 'Doctor')

  可以无数次调用这个工厂函数,每次都会返回一个包含两个属性和一个方法的对象

  工厂模式虽然解决了创建多个相似对象的问题,但是没有解决对象识别问题,即不能知道一个对象的类型

 

 2.构造函数模式

function Person(name, job) {  this.name = name  this.job = job  this.sayName = function() {    console.log(this.name)  }}var person1 = new Person('Jiang', 'student')var person2 = new Person('X', 'Doctor')

没有显示的创建对象,使用new来调用这个构造函数,使用new后会自动执行如下操作

  • 创建一个新对象

  • 这个新对象会被执行[[prototype]]链接

  • 这个新对象会绑定到函数调用的this

  • 返回这个对象

  使用这个方式创建对象可以检测对象类型

person1 instanceof Object // true

person1 instanceof Person //true

  但是使用构造函数创建对象,每个方法都要在每个实例上重新创建一次

 

 3.原型模式

function Person() {}Person.prototype.name = 'Jiang'Person.prototype.job = 'student'Person.prototype.sayName = function() {  console.log(this.name)}var person1 = new Person()

  将信息直接添加到原型对象上。使用原型的好处是可以让所有的实例对象共享它所包含的属性和方法,不必在构造函数中定义对象实例信息。

 

  原型是一个非常重要的概念,在一篇文章看懂proto和prototype的关系及区别中讲的非常详细

  更简单的写法

function Person() {

}

Person.prototype = {

  name: 'jiang',

  job: 'student',

  sayName: function() {

    console.log(this.name)

  }

}

var person1 = new Person()

  将Person.prototype设置为等于一个以对象字面量形式创建的对象,但是会导致.constructor不在指向Person了。

  使用这种方式,完全重写了默认的Person.prototype对象,因此 .constructor也不会存在这里

Person.prototype.constructor === Person  // false

  如果需要这个属性的话,可以手动添加

function Person() {

}

Person.prototype = {

  constructor:Person

  name: 'jiang',

  job: 'student',

  sayName: function() {

    console.log(this.name)

  }

}

  不过这种方式还是不够好,应为constructor属性默认是不可枚举的,这样直接设置,它将是可枚举的。所以可以时候,Object.defineProperty方法

Object.defineProperty(Person.prototype, 'constructor', {

  enumerable: false,

  value: Person

})

  缺点

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

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

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

  friends存在与原型中,实例person1和person2指向同一个原型,person1修改了引用的数组,也会反应到实例person2中

 

 4.构造函数+原型

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

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

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

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

转载于:https://www.cnblogs.com/zifayin/p/8445012.html

你可能感兴趣的文章
VSCode Python开发环境配置
查看>>
208道 java 高频面试题和答案
查看>>
nginx反向代理配置
查看>>
MySQL学习笔记 初学基础篇
查看>>
一步步教你用 CSS 为 SVG 添加过滤器
查看>>
TeeChart Pro VCL/FMX教程(一):入门——构建图表
查看>>
微服务架构 SpringCloud(二)Eureka(服务注册和服务发现基础篇)
查看>>
oracle RAC的客户端HA配置
查看>>
VsCode编辑器
查看>>
spring cloud开发、部署注意事项
查看>>
又一款基于BCH开发出来的社交软件BlockPress
查看>>
ttlsa教程系列之mongodb——(五)mongodb架构-复制原理&复制集
查看>>
虚拟主机通过修改.htaccess将入口重定向到public文件夹
查看>>
nginx快速安装
查看>>
Kinect for windows的脸部识别
查看>>
MySQL 运维笔记(一)—— 终止高负载SQL
查看>>
Carrie Higbie:数据中心的绿色布线之道
查看>>
ECS之初体验
查看>>
我的友情链接
查看>>
【风云原创】Flash技术将被Html5枪毙,Silverlight将何去何从?
查看>>