js 面向对象

// js工厂方法
var person = new Object();
person.name= "lin3615";
person.age = 30;
person.job = "PHPer";

person.sayName = function(){
    alert(this.name);
};

person.sayName(); // lin3615

明显缺点是:使用同一个接口创建很多对象,会产生大量重复的代码。

// js 工厂方法的变种,利于封装
function cp(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 person1 = cp("lin3615", 26, "m");
var person2 = cp("test", 30, "mm");
person1.sayName(); // lin3615
person2.sayName(); // test

解决了创建多个相似对象的问题,缺点是没有解决对象识别的问题(即怎样知道一个对象的类型)

// 构造函数模式
function Person(name, age, job)
{
    this.name = name;
    this.age = age;
    this.job = job;

    this.sayName = function(){
        alert(this.name);
    };
    
}

var person1 = new Person("lin3615", 26, "PHPer");
var person2 = new Person("test", 30, "m");

//person1.sayName();
//person2.sayName();



/*
// 与上面工厂模式的变体的区别
1.没有显式地创建对象
2.直接将属性和方法赋给了 this 对象
3.没有 return 句

以这种方式调用构造函数实际上会经历以下四个步骤:
A。创建一个新对象;
B。将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象)
C. 执行构造函数中的代码(为这个新对象添加属性)
D.返回新对象

创建自定义的构造函数意味着将来可以将它的实例标识为一种特定的类型;而这正是构造函数模式胜过工厂模式的地方
*/

// 作为构造函数使用
//var person = new Person("lin3615", 26, "PHPer");
//person.sayName();


// 作为普通函数使用
//Person("lin3615", 26, "PHPer"); // 添加到 window中去
//window.sayName(); // lin3615

// 在另一个对象的作用域中调用
var o = new Object();
Person.call(o, "lin3615", 26, "PHPer");
// o.sayName(); // lin3615
//构造函数的问题:就是每个方法都要在每个实例上重新创建一遍

/*
原型模式
我们创建的每个函数都有一个 prototype(原型)属性,这个属性是一个对象,它的用途是包含可以由特定类型的所有实例共享的属性和方法。可以这么理解,prototype 就是通过调用构造函数而创建的那个实例的原型对象。好处是可以让所有对象实例共享它的所包含的属性和方法*/

function Person(){}

Person.prototype.name = "lin3615";
Person.prototype.age = 20;
Person.prototype.job = "PHPer";
Person.prototype.sayName = function(){
    alert(this.name);
};

var person1 = new Person();
person1.sayName(); // lin3615

原文地址:https://www.cnblogs.com/lin3615/p/3645231.html