在JavaScript建立对象(三)——原型模式中,咱们阐述了原型模式存在的两个问题:一是没办法经过构造函数初始化对象属性,二是共享引用类型的数据致使数据错乱。因而咱们提出组合使用两种模式,摒弃它们的缺点,保留它们的优势。javascript
为了解决构造函数模式相同功能的函数定义屡次的问题,咱们提出了原型模式。可是不要忘记,构造函数模式也具有原型模式所缺少的优势,好比能够经过构造函数初始化对象的属性,同时也没有共享引用类型的数据错乱问题。既然咱们提出原型模式是为了解决构造函数模式的函数问题,那为何咱们不仅把函数定义在原型中,属性依然保留在构造函数中呢?顺着这个思路,咱们来看下面的代码:java
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 p1 = new Person('张三', 18, 'JavaScript'); var p2 = new Person('李四', 20, 'Java'); p1.friends.push('小红'); console.log(p1.friends);//["小明", "小刚", "小红"] console.log(p2.friends);//["小明", "小刚"] console.log(p1.friends === p2.friends);//false console.log(p1.sayName === p2.sayName);//true
仍是原来的例子,只不过把一些不须要共享的属性保留在构造函数中,须要共享的属性定义在原型中,这就是组合使用构造函数和原型模式。咱们能够看到,首先能够经过构造函数初始化对象属性了。其次,由于属性是定义在构造函数中,每次经过new
关键字建立对象都会执行一次构造函数,因此对于每一个对象来讲就都有了属于本身的属性了。好比这里,p1
的friends
新增了一个小红,p2
的friends
并不会受到影响,由于它们是两个数组。再者,一些须要共享的属性依然定义在原型中,避免了重复定义,可谓是集两种模式之长。数组
这种构造函数与原型集成的模式,是目前在JavaScript中使用最普遍、认同度最高的一种建立自定义类型的方法。能够说,这是用来定义引用类型的一种默认模式。函数
本文参考《JavaScript高级程序设计(第3版)》this