javascript 构建对象的方法

一、工厂模式

function createPerson(name, age, job) {
  var person = {};
  Object.defineProperties(person, {
    _name: { writable: false, value: name},
    _age:{writable:true, value: age},
    job: {writable: true, value: job},
    name:{
    get: function(){return this._name}
    },
    age:{
     get: function(){return this._age;},
     set: function(newValue){this._age = newValue},
    },
  });
  return person;
}

使用工厂模式可以有效的创建一个对象,但是却无法知道一个工厂模式对象实例的类型,例如在控制台中打印:

console.log(person instanceof createPerson);

会得到 false, 从而无法得知对象类型。

创造函数模式

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

如果此时实例化一个 person 的对象, 那么该实例会得到一个叫 constructor 的属性, 这个属性指向 Person。

person.constructor === Peron   // true 
// above is the same as below
person instanceof Person 

同时构造函数模式可以作为函数使用, 而返回的值则会挂在 window 对象上

Person("Greg", 27, "Doctor");
alert(window.name);

这时候会出现一个问题:

this.sayName = new Function("console.log(this.name)");

上面这行代码和构造函数中的sayName 是逻辑等价, 也就是说 this.sayName 实际上创建的是一个匿名函数对象(原型),这种方式创建函数,则会导致不同的作用域链和标识符解析,但是实际上function的运行机制是一样的,也就是说,一旦使用该方法创建了两个或以上实例,相当于创建了两个或以上的一模一样功能的函数。

原型模式

function Person() {
}

Person.prototype.name = "Nicholas";
Person.prototype.age = 28;
Person.prototype.job = "doctor";
Person.prototype.sayName = function(){
console.log(this.name);
}

var person1 = new Person();
var person2 = new Person();
person1.name = "Elizabeth";
if(person1.name === person2.name);   // false

原型模式虽然可以通过对象实例访问对象原型中的值,单不能通过对象实例重写原型中的值,对象实例中重写的值会直接覆盖掉原型的值,而不是重写它:

var person1 = new Person();
var person2 = new Person();
person1.name = "Elizabeth";
console.log(person1.name); //Elizabeth
delete person1.name;
console.log(person1.name); //Nicholas
更简单的原型模式
function Person(){
}

Person.prototype = {
    name:"Nicholas",
    age:27,
    job:"doctor",
    sayName:function() {
    return this.name;
  }
}

Object.defineProperties(person.prototype, "constructor", {
enumerable: false,
value: Person,
});
原型模式的共享本性
function Person(){
}

Person.prototype = {
    name:"Nicholas",
    age:27,
    job:"doctor",
    friends: ["Gerg","Court"],
    sayName:function() {
    return this.name;
  }
}
var person1 = new Person();
var person2 = new Person();

person1.friends.push("Van");

console.log(person1.friends); // "Gerg","Court","Van"
console.log(person1.friends); //"Gerg","Court","Van"

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

function Person(name, age, job){
this.name = name;
this.age = age;
this.friends = ["Shelby","Court"];
}

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

Object.definePropertites(Person, "constructor", {
enumerable: false,
value : Person,
})

动态原型模式

function Person(name, age, job){
  this.name = name;
  this.age = age;
  this.friends = ["Shelby","Court"];
  if( typeof this.sayName !== "function"){
    Person.prototype.sayName = function() {
    return this.name;
  }
 }
}

寄生构造函数模式

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

稳妥构造函数模式

稳妥构造函数模式用以创建私有属性:

function DurableBook(name, year, edition){
  var name = name;
  var year = year;
  var edition = edition;

  this.getName = function(){
    return name;
  }
  this.setName = function(newvalue){
    name = newvalue;
  }
}

var durable = new DurableBook("durable",2006,1);
console.log(durable.getName()); // durable
durable.setName("delicate");
console.log(durable.getName()); // delicate
console.log(durable.name); // undefined

你可能感兴趣的:(javascript 构建对象的方法)