关于javascript:js-创建对象的多种方式优缺点

43次阅读

共计 2620 个字符,预计需要花费 7 分钟才能阅读完成。

本文为 <<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() // 1
o2.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() // 1
o2.sayName() // 2

长处:多个实例共享在全局作用域中定义的函数,解决了两个函数做同一件事的问题
毛病:全局作用域定义的函数实际上只能被某个对象调用,全局作用域徒有虚名,而且如果对象须要定义很多办法,须要创立很多个全局函数,这让自定义的对象类型没有封装个性。

原型模式

咱们创立的每个函数都有一个 protoype 属性,这个属性是一个指针,指向一个对象。这个对象的用处是蕴含了能够由特定类型的所有实例共享的属性和办法。即 prototype 就是由构造函数创立的那个对象实例的原型对象。

function Person(){}
Person.prototype.name = '123'
Person.prototype.age = 18
Person.prototype.sayName = function() {console.log(this.name)
}
var o1 = new Person(1,11)
var o2 = new Person(2,22)
o1.sayName() // 123
o2.sayName() // 123

长处:解决了实例共享属性或事件的问题
毛病:因为实例共享属性的起因,对于值为援用类型的属性来说,一个实例的批改会导致其余实例拜访值更改。如:

function Person(){}
Person.prototype.name = '123'
Person.prototype.age = 18
Person.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() // 1
o2.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() // 1
o2.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,在一些平安的环境应用
毛病:与工厂模式类似,无奈辨认对象所属类型

正文完
 0