本文为<<JavaScript高级程序设计>>的学习笔记。
晚期创立形式
var obj = new Object()obj.name ='xxx'obj.age = 18或应用对象字面量var o1 = { name: 'xxx', say: () => {}}var o2 = { name: 'xxx', say: () => {}}
毛病:应用同一个接口创立很多对象,会产生大量反复代码
工厂模式
function factory(name,age) { var obj = new Object() obj.name = name obj.age = age return obj}var o1 = factory(1, 11)var o2 = factory(2, 22)
长处:解决了创立多个类似对象代码反复问题
毛病:无奈辨认对象是什么类型
构造函数模式
ECMAScript中能够应用构造函数创立特定类型的对象,如Object,Array这种原生构造函数。此外,也能够创立自定义构造函数,从而定义自定义对象的属性和办法。
function Person(name, age) { this.name = name this.age = age this.sayName = function() { console.log(this.name) }}var o1 = new Person(1,11)var o2 = new Person(2,22)o1.sayName() // 1o2.sayName() // 2
长处:构造函数模式创立的实例能够辨别类型标识(instanceof 判断)
毛病:每个办法都须要在实例上从新创立,如 两个实例的sayName办法工作雷同,然而理论创立了两个Function实例
构造函数模式优化
function Person(name, age) { this.name = name this.age = age}function sayName () { console.log(this.name)}var o1 = new Person(1,11)var o2 = new Person(2,22)o1.sayName() // 1o2.sayName() // 2
长处:多个实例共享在全局作用域中定义的函数,解决了两个函数做同一件事的问题
毛病:全局作用域定义的函数实际上只能被某个对象调用,全局作用域徒有虚名,而且如果对象须要定义很多办法,须要创立很多个全局函数,这让自定义的对象类型没有封装个性。
原型模式
咱们创立的每个函数都有一个protoype属性,这个属性是一个指针,指向一个对象。这个对象的用处是蕴含了能够由特定类型的所有实例共享的属性和办法。即prototype就是由构造函数创立的那个对象实例的原型对象。
function Person(){}Person.prototype.name = '123'Person.prototype.age = 18Person.prototype.sayName = function() { console.log(this.name)}var o1 = new Person(1,11)var o2 = new Person(2,22)o1.sayName() // 123o2.sayName() // 123
长处:解决了实例共享属性或事件的问题
毛病:因为实例共享属性的起因,对于值为援用类型的属性来说,一个实例的批改会导致其余实例拜访值更改。如:
function Person(){}Person.prototype.name = '123'Person.prototype.age = 18Person.prototype.friends = ['a', 'b']Person.prototype.sayName = function() { console.log(this.name)}var o1 = new Person(1,11)var o2 = new Person(2,22)o1.friends.push('c')console.log(o2.friends) // ['a', 'b', 'c']
构造函数和原型模式组合
function Person(name, age) { this.name = name this.age = age this.friends = ['a']}Person.prototype = { constructor: Person, sayName: function() { console.log(this.name) }}var o1 = new Person(1,11)var o2 = new Person(2,22)o1.sayName() // 1o2.sayName() // 2
长处:每个实例有本人的属性,同时又共享着办法的援用,还反对传参数
动静原型模式
function Person(name, age) { this.name = name this.age = age this.friends = ['a'] if(typeof this.sayName != 'function') { Person.prototype.sayName = function() { console.log(this.name) } }}var o1 = new Person(1,11)var o2 = new Person(2,22)o1.sayName() // 1o2.sayName() // 2
长处:仅在办法不存在的时候创立一次,防止反复创立
寄生构造函数模式
function SpecialArray() { var o = new Array() // 增加值 o.push.apply(o, arguments) // 增加办法 o.toPipedString = function(){ return this.join('|') } return o}var o1 = new SpecialArray(1,11)o1.toPipedString() // 1|11
长处:在不更改原始构造函数的状况下为对象增加非凡办法
毛病:返回的对象与构造函数以及构造函数的原型没有任何关系,该办法与在构造函数内部创立的对象没有什么不同
稳当构造函数模式
function Person(name) { var o = new Object() // 增加办法 o.getName = function(){ return name } return o}var o1 = new Person(1)o1.getName() // 1
与寄生构造函数不同在于,不应用this,不应用new调用
长处:除了应用getName外没有任何办法可能拜访name,在一些平安的环境应用
毛病:与工厂模式类似,无奈辨认对象所属类型