- 构造函数本身就是一个函数,只不过该函数是出于创建对象的目的而定义的。
创建Object实例的两种方式:
-
new 操作符
var person = new Object(); person.name = "yehui"; person.age = 20;
-
对象字面量
var person ={ name : 'yehui', age : 20 }
创建对象
虽然用Object构造函数或对象字面量都可以创建对象,但是有很大的缺点,就是我们在使用同一个接口创建很多对象的时候,会产生大量的重复代码。
-
工厂模式
是软件工程一种广为人知的设计模式,这种模式抽象了创建具体对象的过程。考虑到ES5中没有类,开发人员发明了一种函数,这种函数用来封装特定的接口创建对象的细节。工厂模式解决了创建多个相似对象的问题,但是没有解决对象识别的问题(即怎么知道一个对象的类型)。
于是我们有了构造函数模式 -
构造函数模式
使用构造函数模式解决了对象识别的问题,也于是我们这个解决了多个函数同做一件事的问题。但是我们通过构造函数模式创建对象时,在全局作用域中定义的函数实际上只能被某个对象调用,这让全局对象作用域有点名副其实。还有就是如果对象需要定义很多方法,那末就要定义很多个全局函数,那么我们这个自定义的引用类型就没有封装性可言。所以我们有了原型模式。 -
原型模式
利用这种模式我们可以让所有对象的实例共享同一个资源,就是说我们不必再构造函数中定义对象实例的信息,而是将这些信息直接添加到源性对象中去。虽然我们的原型模式解决了对象实例共用一个属性或方法的问题,我们也可以给实例自定义属性,因为其可以屏蔽原型中的相同名字的属性,但是当我们有了两个对象的实例相等时,当我们改变一个和源性对象有相同名字的属性的时候,那么两个对象实例的该属性都会受到影响,因为他们指向同一个源性对象。 -
组合使用构造函数模式和原型模式
构造函数模式用来定义实例属性,原型模式用于定义方法和共享的属性。结果,每一个实例都会有自己的一份实例属性的副本,但是同时哟共享着对方的引用,最大限度的节省了内存。function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.friends = ["yehuii", "bob"]; } Person.prototype = { constructor : Person, sayName : function(){ alert(this.name) } } var person111 = new Person("tom", 22, "gmigjgrf"); var person222 = new Person("tim", 55, "doctor"); person111.friends.push("van"); console.log(person111.friends); console.log(person222.friends); console.log(person111.friends === person222.friends); console.log(person111.sayName === person222.sayName);
组合式的模式就解决了,两个对象之间的相互影响。这种对象的创建模式是当前最受欢迎的一种,也是认同度最好的一种。
-
动态原型模式
有经验的开发人员看到独立的构造函数和原型时,很可能会感到困惑,动态原型模式就是致力于解决这类的问题,他把所有的信息都封装在一个构造函数中,而通过在构造函数中初始化原型,而保持了同时使用构造函数和原型的优点。简单的说,就是通过检查某个应该存在的方法是否有效来决定是否需要初始化原型。function Person(name, age, job){ this.name = name; this.age = age; this.job = job; //这个是方法,他只会在sayName不存在的时候才添加到原型中去,这段代码只会在初次调用时才会执行 if(typeof this.sayName != "function"){ Person.prototype.sayName = function(){ alert(this.name); } } } var friend = new Person('yemengmeng', 15, 'meinv'); friend.sayName();
-
待续