看了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属性不再指向Person function 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操作符。
时间: 2024-12-25 02:10:26