Js因为没有类的概念,所以创建对象时就会有许多的问题,下面列举几种创建对象的模式. 现在前面做一个列表 一 工厂模式 二 构造函数模式 三 原型模式 四 组合使用构造函数模式和原型模式 五 动态原型模式 六 寄生构造模式 七 稳妥构造函数模式 工厂模式 用函数来封装一特定的接口创建对象的细节
function createPerson(name, age, job) { var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function(){ alert(name); } return o; } var person1 = createPerson("bob",29,"Doctor"); person1.sayName();//bob工厂模式不能解决对象识别的问题 构造函数模式 js中的构造函数可用来产检特定类型的对象。像Object和Array这样的原生构造函数,在运行是自动出现在执行环境中。此外,也可以创建自定义的构造函数,从而定义自定义对象类型的属性和方法。
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = function(){ alert(name); } } var person1 = new Person("bob",29,"Doctor"); person1.sayName();//bob在构造函数中Person函数取代了createPerson函数,在构造函数中 没有显示的创建对象 直接将属性和方法赋给了this对象 没有return语句 要创建Person的新实例,必须使用new操作符,用这种方法来调用构造函数实际上会经历一下4个步骤: 1.创建一个新对象 2.将构造函数作用域赋给性新对象(因此this指向这个新对象) 3.执行构造函数中的代码 4.返回新的对象 前面的person1有一个构造函数属性,该属性指向Person。 alert(person1.constructor == Person);//true 当然也可以使用类型检测instanceof来检测 alert(person1 instanceof Object);//true alert(person1 instanceof Person);//true 在构造函数模式中每一个对象都有自己的一个方法,导致重用性不高.
alert(person1.sayName == person2.sayName);//false原型模式 我们创建的每一个函数都有一个prototype属性,这个属性是一个对象,他的用途包含可以由特定类型的所有实例共享的属性和方法。按照字面意思来理解,那么prototype就是通过调用构造函数而穿件的那个对象的原型对象。使用原型的好处就是可以让所有的对象实例共享他所包含的属性和方法。
function Person(){ } Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Doctor"; Person.prototype.sayName = function () { alert(this.name); } var person1 = new Person(); person1.sayName();//Nicholas var person2 = new Person(); person2.sayName();//Nicholas alert(person1.sayName == person2.sayName);//true无论什么时候,只要创建了一个函数,就会根据一组特定的规则为该函数创建一个prototype属性,在默认情况下,所有prototype属性都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针. 创建了自定义函数之后,其原型属性默认只会取得constructor属性;至于其他方法则是从Object继承过来的。当调用构造函数创建一个实例后,该实例的内部将包含一个指针,指向构造函数的原型属性。注意:这个属性存在于这个实例和构造函数原型之间而不是实例和构造函数之间. 组合使用构造函数模式和原型模式 创建自定义类型的最常见的方式就是组合使用构造函数模式与原型模式.构造函数用于定义属性而原型模式用于定义方法.
/** * Created by lenovo on 2017/4/8. */ function Person(name, age, job) { this.name = name; this.job = job; this.age = age; } Person.prototype = { constructor : Person, sayName : function () { alert(this.name); } } var person1 = new Person("Nicholas",29,"Doctor"); var person2 = new Person("Bob",30,"Student"); alert(person1.sayName());//Nicholas alert(person2.sayName());//Bob动态原型模式 为了将原型和构造函数写到一起,所以出现了动态原型模式
function Person(name, age, job) { this.name = name; this.job = job; this.age = age; if(typeof this.sayName != "function") { Person.prototype.sayName = function () { alert(this.name); } } }寄生构造函数模式 通常在前集中模式都不适用的情况下,可以使用寄生构造函数模式.这种迷失的基本思想是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新创建的对象;但从表面看,这个函数又很想是典型的构造函数.
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 person = new Person("Bob",29,"doctor"); person.sayName();//Bob在这个例子中,Person函数创建了一个新对象,并且以相应的属性和方法初始化该对象,然后又返回了这个对象.除了使用new操作符并把包装的函数叫做构造函数之外和工厂模式其实是一模一样的.构造函数在不返回值的情况下,默认会返回新对象.而通过在构造函数的末尾加一个return语句,可以重写调用构造函数时返回的值. 稳妥构造函数模式 道格拉斯.克罗克德福发明了js中的稳妥对象这个概念值得是没有公共属性,而且其方法也不引用this对象.
function Person(name, age, job){ var o = new Object(); o.sayName = function(){ alert(name); } return o; } var person = Person("bob",29."doctor"); person.sayName();//bob这样变量person中保存的是一个稳妥对象,而除了调用sayName()方法外,没有别的方式可以访问到其数据成员。
