首页 > 代码库 > JavaScript中创建对象的几种模式

JavaScript中创建对象的几种模式

看了js高级程序设计的第六章,很多知识。关于创建对象的几种模式,这里记录一下。

 

1.工厂模式

 1 function createPerson(name, age, job) { 2     var o = new Object(); 3     o.name = name; 4     o.age = age; 5     o.job = job; 6     o.sayName = function() { 7         return this.name; 8     }; 9     return o;10 }

没有解决对象识别的问题,不能知道一个对象的类型

2.构造函数模式

function Person(name, age, job) {    this.name = name;    this.age = age;    this.job = job;    this.sayName = function() {        alert(this.name);    };}var person1 = new Person("Nicholas", 29, "Software Engineer");var person2 = new Person("Greg", 27, "Doctor");alert(person1.constructor == Person);alert(person2.constructor == Person);alert(person1 instanceof Object);alert(person1 instanceof Person);alert(person2 instanceof Object);alert(person2 instanceof Person);//当作构造函数使用var person = new Person("Nicholas", 29, "Software Engineer");person.sayName();//当作普通函数使用Person("Greg", 27, "Doctor");window.sayName();//在另一个对象的作用域中调用var o = new Object();Person.call(o, "Kristen", 25, "Nurse");o.sayName();

(1)以new操作符调用原生构造函数模式创建对象;
(2)给了实例一个特定的类型;
(3)既可用于创建对象,又可当作普通函数用。

3.原型模式

function Person() {}Person.prototype.name = "Nicholas";Person.prototype.age = 29;Person.prototype.job = "Software Engineer";Person.prototype.sayName = function() {    alert(this.name);};var person1 = new Person();person1.sayName();var person2 = new Person();person2.sayName();alert(person1.sayName == person2.sayName);//alert(Person.prototype.isPrototypeOf(person1));//alert(Person.prototype.isPrototypeOf(person2));alert(Object.getPrototypeOf(person1) == Person.prototype);alert(Object.getPrototypeOf(person1).name);function hasPrototypeProperty(object, name) {    return !hasOwnProperty(name) && (name in object);}var person = new Person();alert(hasPrototypeProperty(person, "name"));person.name = "Greg";alert(hasPrototypeProperty(person, "name"));var keys = Object.getOwnPropertyNames(Person.prototype);alert(keys);//更简单的原型语法:此时constructor属性不再指向Personfunction Person() {};Person.prototype = {    name : "Nicholas",    age : 29,    job : "Software Engineer",    sayName : function() {        alert(this.name);    }};var friend = new Person();Person.prototype.sayHi = function() {    alert("Hi");};friend.sayHi();function Person() {};Person.prototype = {    constructor : Person,    name : "Nicholas",    age : 29,    job : "Software Engineer",    friends : ["Shelby", "Court"],    sayName : function() {        alert(this.name);    }};var person1 = new Person();var person2 = new Person();person1.friends.push("Van");alert(person1.friends);alert(person2.friends);alert(person1.friends === person2.friends);

(1)理解原型对象是重点,构造函数中prototype属性指向原型,原型中constructor属性又指向构造函数,实例中的prototype属性也指向原型,是指针不是副本;
(2)使用更简单的原型语法相当于重写原型,此时constructor属性需要显示设置指向构造函数;
(3)对于引用类型来说,一个实例给原型增删属性会影响其他实例。

4.构造函数模式和原型模式组合/动态原型模式

采用组合的构造函数模式与原型模式,构造函数定义实例属性,原型定义共享属性和方法。动态原型模式是在原型模式基础上,通过if判断需不需要在原型中定义属性或方法。

//动态原型模式function Person(name, age, job){    //属性    this.name = name;    this.age = age;    this.job = job;    this.friends = ["Shelby", "Court"];    //方法    if (typeof this.sayName != "function"){        Person.prototype.sayName = function() {            alert(this.name);        };    }}Person.prototype = {    constructor : Person,    sayName : function(){        alert(this.name);    }}var person1 = new Person("Nicholas", 29, "Software Engineer");var person2 = new Person("Greg", 27, "Doctor");person1.friends.push("Van");alert(person1.friends);alert(person2.friends);alert(person1.friends === person2.friends);alert(person1.sayName === person2.sayName);

(1)目前最受欢迎的就是组合模式

5.寄生构造函数模式

/*寄生构造函数模型*/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;}var friend = new Person("Nicholas", 29, "Software Engineer");friend.sayName();function SpecialArray(){    var values = new Array();    values.push.apply(values, arguments);    values.toPipedString = function() {        return this.join("|");    };    return values;}var colors = new SpecialArray("red", "blue", "green");alert(colors.toPipedString());

(1)用来利用原生对象定制自己特殊功能的对象;
(2)同等条件下,不推荐使用。

6.稳妥构造函数模式

(1)只有构造函数内部的方法可以访问私有成员,其他不能访问;(2)这种方法较为安全,但不能用instanceof操作符。

JavaScript中创建对象的几种模式