Javascript学习之建立对象

在Javascript中,除了几种原始类型外,其他皆为对象(Object,Array ...),既然对象如此重要,那就列举一下在Javascript中如何建立对象:javascript

经过Object构造函数建立对象实例
var person = new Object();
person.name = 'krew';
person.age = 26;
对象字面量

对象字面量是对象定义的一种简写形式,目的在于简化建立包含大量属性的对象的过程。java

var person = {
  name : 'krew',
  age : 26
}
工厂模式

工厂模式是一种设计模式,经过对建立具体对象的过程进行抽象。使用函数来封装建立对象的细节,能够无数次地调用用该函数,每次均可以获得包含制定内容的对象。设计模式

function personFactory(name, age){
  var obj = new Object();
  obj.name = name;
  obj.age = age;
  obj.sayName = function(){
    console.log(this.name);
  }
  return obj;
}

var person1 = personFactory('krew', 26);  
var person2 = personFactory('john', 20);
构造函数模式

基于工厂模式建立对象虽然方便,可是建立出来的对象没有特定的对象类型(好比原生对象Object, Array的实例都有本身的类型),因此就采用构造函数模式来建立对象,就能解决识别对象类型的问题。数组

function Person(name, age){
  this.name = name;
  this.age = age;
  this.sayName = function() {
    console.log(this.name);
  }
}

var person1 = new Person('krew', 26);
var person2 = new Person('john', 20);

person1.sayName();  // 'krew'
person2.sayName();  // 'john'

person1.constructor == Person  // true
person2.constructor == Person  // true
原型模式

每一个函数在建立的时候,就会根据特定的规则为该函数建立一个prototype属性,这个属性是指向函数的原型对象的指针。这个原型对象的包含能够由特定类型的全部实例共享的属性和方法。因此,在构造函数的prototype属性上添加属性与方法,该构造函数的全部实例都会在原型链上查找到这些属性与方法。函数

function Person() {
}
Person.prototype.name = 'krew';
Person.prototype.age = 26;
Person.prototype.sayName = function() {
  console.log(this.name);
}

var person1 = new Person();
var person2 = new Person();

person1.sayName();  // 'krew'
person2.sayName();  // 'krew'
组合构造函数和原型模式

因为原型对象中的属性是被不少实例所共享的,对于引用类型的属性值,将会存在实例间没法隔离的问题:this

function Person() {
}
Person.prototype = {
  constructor : Person,
  name : 'krew',
  age : 26,
  friends : ['john', 'kitty'],
  showFriends : function() {
    console.log(this.friends);
  }
}
var person1 = new Person();
var person2 = new Person();

person1.friends.push('petter');

person1.showFriends()  // ['john', 'kitty', 'petter']
person2.showFriends()  // ['john', 'kitty', 'petter']

能够看到,仅是在实例person1的friends属性上添加值,但person2也跟着变化。这是由于friends数组存在于Person.prototype而非person1中,person1与person2中的friends皆为引用Person.prototype中的friends,因此当经过person1来改变friends的时候,person2中的friends也会反映出来。
经过组合构造函数与原型模式能够解决上面出现的问题,构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性,每一个实例会有本身的一份实例属性,同时又共享着方法的引用,极大的节省了内存。prototype

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

Person.prototype.sayName = function() {
  console.log(this.name);
}

var person1 = new Person('krew', 26);
var person2 = new Person('john', 20);

person1.sayName();  // 'krew'
person2.sayName();  // 'john'
动态原型模式
function Person(name, age){
  this.name = name;
  this.age = age;
  if (typeof this.sayName != 'function') {
    Person.prototype.sayName = function() {
      console.log(this.name);
    }
  }
}

var person1 = new Person('krew', 26);
var person2 = new Person('john', 20);

person1.sayName();  // 'krew'
person2.sayName();  // 'john'
寄生构造函数模式
function Person(name, age) {
  var obj = new Object();
  obj.name = name;
  obj.age = age;
  obj.sayName = function() {
    console.log(this.name);
  }
  return obj;
}

var person1 = new Person('krew', 26);
var person2 = new Person('john', 20);

person1.sayName();  // 'krew'
person2.sayName();  // 'john'
稳妥构造函数模式
function Person(name) {
  var obj = new Object();
  obj.sayName = function() {
    console.log(name);
  }
  return obj;
}

var person1 = Person('krew');
var person2 = Person('john');

person1.sayName();  // 'krew'
person2.sayName();  // 'john'
相关文章
相关标签/搜索