笔记-javascript创建对象
1. 工厂模式创建对象
1 //在函数内创建一个对象,给对象赋予属性及方法再将对象返回 2 function person (name, age) { 3 var obj = new Object(); 4 obj.name = name; 5 obj.age = age; 6 obj.sayName = function () { 7 alert(this.name); 8 }; 9 return obj; 10 } 11 var per = person("zhangsan", 21); 12 per.sayName();//zhangsan 13 //工厂模式无从识别对象的类型,全部都是Object 14 alert(typeof per); //object
缺点:没有new,重复调用方法,资源浪费。
2.构造方法创建对象
1 //没有显示的创建对象,直接将属性和方法赋值给了this对象,没有return语句 2 function Person (name, age) { 3 this.name = name; 4 this.age = age; 5 //相当于this.sayName = new Function ("alert(this.name)"); 6 this.sayName = function () { 7 alert(this.name); 8 }; 9 } 10 //使用new创建对象, 11 var person = new Person("zhangsan", 21); 12 var person2 = new Person("lisi", 21); 13 person.sayName();//zhangsan 14 //能够识别对象(这正是构造函数模式胜于工厂模式的地方) 15 //使用构造函数的最大的问题在于每次创建实例的时候都要重新创建一次方法(理论上每次创建对象的时候对象的属性均不同,而对象的方法是相同的) 16 alert(person instanceof Person);//true 17 alert(person instanceof Object);//true 18 alert(person.sayName == person2.sayName);//false
解决了没有new,但是函数还是重复调用,浪费资源
3.原型模式创建对象
原型类似css里面的class选择器·,一次给一组元素加样式
1 // 我们创建的每个函数都有prototype(原型)属性,这个属性是一个指针,指向一个对象,
而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。使用原型对象的好处就是可以让所有对象实例共享它所包含的属性及方法。 2 function Person () {} 3 Person.prototype.name = "Tom"; 4 Person.prototype.age = 21; 5 Person.prototype.friends = ["Lee", "Jack"]; 6 Person.prototype.sayName = function () { 7 alert(this.name); 8 }; 9 10 var p1 = new Person(); 11 p1.sayName(); //Tom 12 alert(p1.friends); 13 var p2 = new Person(); 14 p2.sayName(); //Tom 15 alert(p2.friends); 16 alert(p1.sayName == p2.sayName); //true 17 //一个实例修改了引用,另一个也随之更改了引用 18 p1.friends.push("john"); 19 alert(p1.friends); //Lee,Jack,john 20 alert(p2.friends); //Lee,Jack,john
解决了没有new,同时也解决了函数重复调用,但是成员属性都一样
4.混合模式创建对象(组合使用构造函数和原型模式)
1 //混合模式中构造函数模式用于定义实例属性,而原型模式用于定义方法和共享属性 2 function Person (name, age) { 3 this.name = name; 4 this.age = age; 5 this.friends = ["Lee", "Jack"]; 6 if (typeof this.sayName != "function") { 7 Person.prototype.sayName = function () { 8 alert(this.name); 9 }; 10 } 11 } 12 13 var p1 = new Person("Tom", 23); 14 var p2 = new Person("Bob", 21); 15 p1.sayName(); 16 alert(p1.friends); 17 p2.sayName(); 18 alert(p2.friends); 19 //一个实例修改了引用,另一个不会更改引用 20 p1.friends.push("john"); 21 alert(p1.friends); 22 alert(p2.friends);
5.原型对象概念
1 // 我们创建的每个函数都有prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。
使用原型对象的好处就是可以让所有对象实例共享它所包含的属性及方法。 2 function Person () {} 3 Person.prototype.name = "Tom"; 4 Person.prototype.age = 21; 5 Person.prototype.sayName = function () { 6 alert(this.name); 7 }; 8 9 var p1 = new Person(); 10 var p2 = new Person(); 11 alert(p1.constructor == Person); //true 12 alert(p1.constructor == Object); //false 13 //检测属性是实例属性还是原型属性 14 // alert(p1.hasOwnProperty("name")); //false 15 // alert("name" in p1); //true 16 // alert(Person.prototype.hasOwnProperty("name")); //true 17 // //检测指示对象是否存在于另一个对象的原型链中 18 // alert(Person.prototype.isPrototypeOf(p1)); //true 19 // alert(Person.prototype.isPrototypeOf(p2)); //true 20 // //返回的对象(Person.prototype)是这个对象(p1)的原型 21 // alert(Object.getPrototypeOf(p1) == Person.prototype); //true 22 // alert(p1.sayName == p2.sayName); //true 23 p1.name = "john"; 24 alert(hasPrototypeProperty(p1, "name")); 25 //检测属性是否属于原型 26 function hasPrototypeProperty (object, name) { 27 return !object.hasOwnProperty(name) && (name in object); 28 }
6.寄生构造函数模式
1 function Person (name, age) { 2 var obj = new Object(); 3 obj.name = name; 4 obj.age = age; 5 obj.sayName = function () { 6 alert(this.name); 7 }; 8 return obj; 9 } 10 var p1 = new Person("Tom", 21); 11 p1.sayName(); 12 //返回的对象与构造函数和构造函数的原型没有关系,相当于在构造函数外部创建对象 13 alert(p1 instanceof Person); //false 14 alert(Person.prototype.isPrototypeOf(p1)); //false
7.原型链
1 function Parent () { 2 this.property = true; 3 this.colors = ["red", "green", "blue"]; 4 } 5 Parent.prototype.getParentValue = function () { 6 return this.property; 7 }; 8 9 function Child () { 10 this.childproperty = false; 11 } 12 //继承Parent 13 Child.prototype = new Parent(); 14 Child.prototype.getChildValue = function () { 15 return this.childproperty; 16 }; 17 18 var instance = new Child(); 19 var instance2 = new Child(); 20 // alert(instance.getParentValue()); //true 21 22 //instance相当于Child,Parent,Object任何一个类型的实例 23 // alert(instance instanceof Child); //true 24 // alert(instance instanceof Parent); //true 25 // alert(instance instanceof Object); //true 26 27 //Object.prototype,Parent.prototype,Child.prototype任何一个相当于instance的原型 28 // alert(Object.prototype.isPrototypeOf(instance)); //true 29 // alert(Parent.prototype.isPrototypeOf(instance)); //true 30 // alert(Child.prototype.isPrototypeOf(instance)); //true 31 32 alert(instance.colors); //ren, green, blue 33 instance.colors.push("yellow"); 34 //因为引用类型的原型属性会被所有的实例共享,所以改变一个实例的引用类型的值时,另外一个实例的引用类型值也会改变 35 alert(instance.colors); //ren, green, blue, yellow 36 alert(instance2.colors); //ren, green, blue, yellow