创建对象的几种模式

对象创建方法其实主要有两种最简单的方式:

  1. 创建一个Object实例
var person = new Object();
person.name = 'jinghong';
person.age = 22;
person.sayName = function(){
    alert(this.name);
  }
  1. 对象字面量
    var person = {
    name = ‘jinghong’,
    age: ‘22’
    }

一、工厂模式

function creatPerson(name, age, job){
  var obj = new Object();
  obj.name = name;
  obj.age = age;
  obj.job = job;
  obj.sayName = function(){
    alert(this.name);
  }
  return obj;
}
var person1 = createPerson('jinghong', 22, 'software engnieer');
var person2 = createPerson('tiantian', 21, 'teacher');

二、构造函数模式

//构造函数模式
function Person(){
  this.name = name;
  this.age = age;
  this.job = job;
  this.sayName = function(){
    alert(this.name);
  }
}
var person1 = new Person('jinghong', 22, 'software engnieer');
var person2 = new Person('tiantian', 21, 'teacher');

注意: 构造函数只是一些使用new 操作符时,被调用的普通函数,并不是一个类。任何函数被new调用时,它就是构造函数;
当一个函数被new表达式中被调用时,他是一个构造函数,他会初始化创建一个新的对象。

使用new来调用函数时会发生一下操作:
  1. 创建一个新的对象
  2. 将构造函数的作用域赋给这个对象(因此这个新对象会绑定到构造函数的this)
  3. 执行构造函数中的代码(为这个新的对象添加属性和方法)
  4. 返回新的对象

在前面的例子中,person1,person2分别是Person的实例;这两个实例对象都有一个constructor属性,该属性指向Person;

console.log(person1.constructor);//Person
console.log(person2.constructor);//Person

构造函数模式和工厂模式不同的地方是,可以将实例标识为一种特定的类型,

console.log(person1 intanceof Object);  //true
console.log(person1 intanceof Person);  //true
构造函数模式的缺点:

构造函数的每个实例中实际上都包含不同的Function实例,即:person1.sayName != person2.sayName
创建两个完成同样任务的Function实例的确没有必要,所以可以通过把函数定义转移到函数外面进行,来解决这个问题:

funtion Person(name, age, job){
      this.name = name;
      this.age = age;
      this.job = job;
      this.sayName = sayName;//一个函数的指针
  }
function sayName(){
  alert(this.name);
 }
 var person3 = new Person('person3', 21, 'doctor');
 person3.sayName();//person3

三、原型模式

function Person(){
}
Person.prototype.name = 'jinghong';
Person.pertotype.age = 29;
Person.prototype.job = 'software Engineer';
Person.pertotype.sayName = funtion(){
  alert(this.name);
 }
var person1 = new Person();
var person2 = new Person();
person1.sayName();//'jinghong';
person2.sayName();//'jinghong'

构造函数为空函数,但是仍然可以通过new构造函数来创建一个新的对象,并且这些对象还会具有相同的属性和方法,但是与构造函数不同的是,新对象的属性和方法是所有实例共享的,所以person1和person2的sayName()方法是同一个函数;

什么是原型对象

在任何时候,只要创建一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象,原型对象在默认情况下拥有一个constructor属性,这个属性指向所在函数的指针,例如:Person.prototype.constructor指向person;
这里写图片描述

不能通过对象实例重写原型中的值

如果我们在实例中添加了一个属性,而属性与实例原型中的一个属性同名,那么我们就在实例中创建该属性,该属性会自动屏蔽原型中的那个属性。

简单的原型语法

 function Person(){
 }
 Person.prototype{
    name : 'jinghong',
    age: 21,
    sayName: function(){
        alert(this.name);
    }
 }

原生对象的原型

通过給原生对象的原型对象添加或者修改方法,可以給基本包装类型添加或者修改方法;
例如:給基包装类型String添加名为startsWith()方法,检测一个字符串是否以某个特定的字符开始

String.prototype.stratWith = function(text){
    return this.indexOf(text) == 0;
     }

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

构造函数用于定义实例属性,原型模式用于定义方法和共享属性,这样所有实例都拥有自己的一份实例属性的副本,同时并拥有对共享方法的引用,最大限度的节省了内存

function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.friends = ['a', 'b', 'c']
}
Person.prototype = {
  constructor : Person;
  sayName : function(){
     alert(this.name);
  }
var person1 = new Person('jinghong', 21, 'engineer');
var person2 = new Person('wenjuan', 21, 'engineer');
person1.friends.push('d');
console.log(person1.friends);//'a', 'b', 'c','d'
console.log(person2.friends);//'a', 'b', 'c'
console.log(person1.friends === person2.friends);//false
console.log(person1.sayName === person2.sayName);//true

五、动态原型模式

function Person(name, age, job){
  //属性
   this.name = name;
   this.age = age;
   this.job = job;

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

在上述代码中只有当以前的原型对象没有sayName方法时,才在原型链中添加sayName方法,并且这段代码只能在初次调用时才会执行,以后原型已经完成初始化,并且以后生成的实例都将具有修改后的sayName方法;

六、寄生构造函数模式

七、稳妥构造函数模式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值