补充:JavaScript 创建对象的七种方式

JavaScript创建对象的方式有很多,通过Object构造函数或对象字面量的方式也可以创建单个对象,显然这两种方式会产生大量的重复代码,并不适合量产。接下来介绍七种非常经典的创建对象的方式,他们也各有优缺点。



工厂模式

 1 function createPerson(name, job) {
 2   var o = new Object()
 3   o.name = name
 4   o.job = job
 5   o.sayName = function() {
 6     console.log(this.name)
 7   }
 8   return o
 9 }
10 var person1 = createPerson(‘Jiang‘, ‘student‘)
11 var person2 = createPerson(‘X‘, ‘Doctor‘)

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

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



 构造函数模式

1 function Person(name, job) {
2   this.name = name
3   this.job = job
4   this.sayName = function() {
5     console.log(this.name)
6   }
7 }
8 var person1 = new Person(‘Jiang‘, ‘student‘)
9 var person2 = new Person(‘X‘, ‘Doctor‘)

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

  • 创建一个新对象
  • 这个新对象会被执行[[prototype]]链接
  • 这个新对象会绑定到函数调用的this
  • 返回这个对象

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

1 person1 instanceof Object // true
2 person1 instanceof Person //true

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



 原型模式

1 function Person() {
2 }
3 Person.prototype.name = ‘Jiang‘
4 Person.prototype.job = ‘student‘
5 Person.prototype.sayName = function() {
6   console.log(this.name)
7 }
8 var person1 = new Person()

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

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

更简单的写法

 1 function Person() {
 2 }
 3 Person.prototype = {
 4   name: ‘jiang‘,
 5   job: ‘student‘,
 6   sayName: function() {
 7     console.log(this.name)
 8   }
 9 }
10 var person1 = new Person()

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

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

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

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

 1 function Person() {
 2 }
 3 Person.prototype = {
 4   constructor:Person
 5   name: ‘jiang‘,
 6   job: ‘student‘,
 7   sayName: function() {
 8     console.log(this.name)
 9   }
10 }

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

1 Object.defineProperty(Person.prototype, ‘constructor‘, {
2   enumerable: false,
3   value: Person
4 })

缺点

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

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

 1 function Person() {
 2 }
 3 Person.prototype = {
 4   name: ‘jiang‘,
 5   friends: [‘Shelby‘, ‘Court‘]
 6 }
 7 var person1 = new Person()
 8 var person2 = new Person()
 9 person1.friends.push(‘Van‘)
10 console.log(person1.friends) //["Shelby", "Court", "Van"]
11 console.log(person2.friends) //["Shelby", "Court", "Van"]
12 console.log(person1.friends === person2.friends) // true

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



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

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

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

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

 1 function Person(name) {
 2   this.name = name
 3   this.friends = [‘Shelby‘, ‘Court‘]
 4 }
 5 Person.prototype.sayName = function() {
 6   console.log(this.name)
 7 }
 8 var person1 = new Person()
 9 var person2 = new Person()
10 person1.friends.push(‘Van‘)
11 console.log(person1.friends)  //["Shelby", "Court", "Van"]
12 console.log(person2.friends) // ["Shelby", "Court"]
13 console.log(person1.friends === person2.friends) //false



动态原型模式

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

 1 function Person(name, job) {
 2   // 属性
 3   this.name = name
 4   this.job = job
 5
 6   // 方法
 7   if(typeof this.sayName !== ‘function‘) {
 8     Person.prototype.sayName = function() {
 9        console.log(this.name)
10     }
11   }
12
13 }
14 var person1 = new Person(‘Jiang‘, ‘Student‘)
15 person1.sayName()

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

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

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

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



 寄生构造函数模式

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

 1 function Person(name, job) {
 2   var o = new Object()
 3   o.name = name
 4   o.job = job
 5   o.sayName = function() {
 6     console.log(this.name)
 7   }
 8   return o
 9 }
10 var person1 = new Person(‘Jiang‘, ‘student‘)
11 person1.sayName()

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

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



稳妥构造函数模式

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

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

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

 1 function Person(name, job) {
 2   var o = new Object()
 3   o.name = name
 4   o.job = job
 5   o.sayName = function() {
 6     console.log(name)
 7   }
 8   return o
 9 }
10 var person1 = Person(‘Jiang‘, ‘student‘)
11 person1.sayName()

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

原文地址:https://www.cnblogs.com/yd-MM/p/9707032.html

时间: 2024-07-29 21:08:41

补充:JavaScript 创建对象的七种方式的相关文章

JavaScript 创建对象的七种方式

转自:xxxgitone.github.io/2017/06/10/JavaScript创建对象的七种方式/ JavaScript创建对象的方式有很多,通过Object构造函数或对象字面量的方式也可以创建单个对象,显然这两种方式会产生大量的重复代码,并不适合量产.接下来介绍七种非常经典的创建对象的方式,他们也各有优缺点. 工厂模式 1 function createPerson(name, job) { 2 var o = new Object() 3 o.name = name 4 o.job

0145 JavaScript创建对象的三种方式 之 字面量:创建,访问对象的属性&方法,变量、属性、函数、方法总结

在 JavaScript 中,现阶段我们可以采用三种方式创建对象(object): 利用字面量创建对象 利用 new Object 创建对象 利用构造函数创建对象 5.2.1 利用字面量创建对象 5.2.1.1 创建 使用对象字面量创建对象:{ }. 就是花括号 { } 里面包含了表达这个具体事物(对象)的属性和方法: { } 里面采取键值对的形式表示 键:相当于属性名 值:相当于属性值,可以是任意类型的值(数字类型.字符串类型.布尔类型,函数类型等) 代码如下: var star = { na

JavaScript创建对象的几种方式总结

ECMA把对象定义为:无序属性的集合,其属性可以包含基本值.对象或者函数. 1. 使用Object构造函数创建对象 创建自定义对象的最简单的方式就是创建一个Object的实例,然后再为它添加属性和方法. //通过Object构造函数的实例创建对象 var person = new Object(); //添加属性和方法 person.name = "guo"; person.age = '24'; person.sayName = function(){ console.log(thi

javascript创建对象的几种方式

1. 简单对象的创建    使用{} 也就是js的单例模式    var Cat = {};//JSON格式 Cat.name="kity";//添加属性并赋值 Cat.age=2; Cat.sayHello=function(){ console.log("hello "+Cat.name+",今年"+Cat["age"]+"岁了");//可以使用“.”的方式访问属性,也可以使用HashMap的方式访问

javascript 创建对象的几种方式

1.通过new Object创建 创建自定义对象的最简单方式就是创建一个Object 的实例,然后再为它添加属性和方法,如下所示. var person = new Object(); person.name = "Nicholas"; person.age = 29; person.job = "Software Engineer"; person.sayName = function(){ alert(this.name); }; 2.通过对象字面量创建对象 v

0146 JavaScript创建对象的三种方式 之 new Object

创建空对象 var andy = new Obect(); 通过内置构造函数Object创建对象,此时andy变量已经保存了创建出来的空对象 给空对象添加属性和方法 通过对象操作属性和方法的方式,来为对象增加属性和方法 示例代码如下: andy.name = '啊哈'; andy.age = 18; andy.sex = '男'; andy.sayHi = function(){ alert('大家好啊~'); } 注意: Object() :第一个字母大写 new Object() :需要 n

0147 JavaScript创建对象的三种方式 之 构造函数

5.2.3.1 构造函数 构造函数:是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与 new 运算符一起使用.我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面. 构造函数的封装格式: function 构造函数名(形参1,形参2,形参3) { this.属性名1 = 参数1; this.属性名2 = 参数2; this.属性名3 = 参数3; this.方法名 = 函数体; } 构造函数的调用格式 var obj = new 构造函数名(实参1,实参2,

JavaScript创建对象的七种方法

一. 工厂模式 创建: function createPerson(name,behavior){ var p=new Object(); p.name=name; p.behavior=behavior; p.getInfo=function(){ alert(this.name+"在"+this.behavior) } p.getInfo();}var person=createPerson("张三",["打游戏","看书"

javascript创建对象的6种方式

/*1.工厂模式*/ function createPerson(name,age,job) { var o = new object(); o.name = name; o.age = age; o.job = job; o.setName = function(newName) { this.name = newName; }; return o; } var person1 = createPerson("zcj", 21, "Soft Engineer");