js创建对象的7种方法

来源:互联网 发布:奥林巴斯25mm1.8知乎 编辑:程序博客网 时间:2024/05/16 10:14

ECMAScript5以及之前没有类的概念,js中每个对象都是基于引用类型创建的


1. 创建对象—工厂模式

使用一个工厂函数来创建对象,该工厂函数接收参数构建对象必要信息,并返回一个对象,每一次调用该工厂函数就返回一个对象
例如:

function createPerson(name, age, sex) {    var o = {};    o.name = name;    o.age = age;    o.sex = sex;    o.sayName = function() {        alert(this.name)    }    return o;}var p1 = createPerson('limi', 20, 'man');conosle.log(p1.name) // 'limi'p1.sayName()   //弹窗'limi'

createPreson函数就像一个工厂源源不断的生产对象;
缺点就是无法判断产生的是什么对象。


2. 创建对象—构造函数模式

有一些原生的构造函数,如Array, Object,可以通过new产生一个新的对象。也可以自定义构造函数,并定义自定义对象的属性和方法。
例如:

function Person(name, age, sex) {    this.name = name;    this.age = age;    this.sex = sex;    this.sayName = function() {        alert(this.name)    }}

再通过new Person('limi', 30, 'woman')生成对象;
缺点是

  • 没有显示地创建对象
  • 并直接将属性和方法赋值给this对象
  • 没有return语句

通过该方法创建的对象都是Person和Object的实例(instanceOf), 通过该方法可以创建特定类型的对象。


3. 创建对象—原型模式

每个函数都有prototype属性,该属性指向一个对象,在原型对象中包含对象实例共享的所以属性与方法。用该方法可以不必在构造函数中定义对象实例信息。如下:

function Person() {}Person.prototype.name = 'tete';Person.prototype.age = 22;Person.prototype.job = 'teacher';Person.prototype.sayName = function() {    alert(this.name)}var person1 = new Person();var person2 = new Person();person1.sayName() //'tete';person1.sayName === person2.sayName

我们将一些属性和sayName()函数直接添加到Person的prototype属性中,声明了一个空的构造函数。通过该构造函数创建的实例都共享原型上的属性与方法,不同实例对象的属性和方法完全相同。
构造函数的原型是一个对象,上面的例子可改写如下:

function Person(){}Person.prototype = {    constructor: Person,    name: 'tete',    age: 33,    job: 'teacher',    sayName: function() {        alert(this.name)    }}

因为完全重写了原型对象,将原型对象中的constructor属性重新指向Person
可以看的通过原型模式创建对象,对象实例共享属性与方法,当某一实例修改其属性或方法时,其他实例再调用该属性或方法时,属性与方法也会是修改后的,这显然不合理。


4. 创建对象—-组合使用构造函数模式和原型模式

这种方法集两种模式之长,使用构造函数模式定义实例属性,原型模式定义方法和共享的属性。因此每个实例都会有一个实例属性的副本还有着共享的方法。例子:

function Person(name, age, job) {    this.name = name;    this.job = job;    this.age = age;    this.friends = ['te1', te2];}Person.prototype = {    constructor: Person,    sayName: function() {        alert(this.name);    }}var p1 = new Person('tete1', 22, 'teaher');var p2 = new Person('tete2', 14, 'student');

此时p1和p2都有自己的属性和共享的方法(原型中),p1和p2都有共同的好友[‘te1’, te2],但是他们都是自己独立的数组副本,当p1添加friend时,不会影响p2的this.friends;


5. 创建对象—-动态原型模式

动态原型模式通过在构造函数中初始化原型,同时保持构造函数和原型的优点。动态的通过检测判断来添加方法。例子:

function Person(name, age, job) {    this.name = name;    this.age = age;    this.job = job;    // 方法    if (typeof this.sayName !== 'function') {        Person.prototype.sayName = function() {            alert(this.name);        }    }}Person.prototype = {    constructor: Person,    sayName: function() {        alert(this.name);    }}

这样在调用构造函数的时候会进行初始化,当不存在sayName函数时会在原型上添加。


6. 寄生构造函数模式

该模式主要是使用一个函数封装创建对象的代码,在返回该对象。例子:

function Person(name, age, job) {    var o = new Object();    o.name = name;    o.age = age;    o.job = job;    o.sayName = function() {        alert(this.name);    }    return o;}

可以看出返回的对象与构造函数或与构造函数的原型之间没有关系。


7. 稳妥构造函数模式

该模式没有公共属性,其方法也不引用this的对象。例子:

function Person(name, age, job) {    var o = new Object();    //定义私有变量和函数    // 添加方法    o.sayName = function() {        alert(name);    }    return o;} var p1 = Person('tete', 11, 'engineer');p1.sayName() //'tete'

这样只有调用sayName()才可以访问其数据成员。



来源javascript高级程序设计

原创粉丝点击