工厂模式javascript
构造函数模式html
原型模式java
function createPerson(name, age){ var obj = new Object(); obj.name = name; obj.age = age; return obj; //必定要返回,不然打印undefined:undefined } var person1 = new createPerson('Young',18); console.log(person1.name + ':' + person1.age);
优势:工厂模式能够解决建立多个类似对象函数
缺点:没有解决对象识别问题(怎样肯定一个对象的类型)学习
学习判断对象类型: http://www.cnblogs.com/flyjs/...this
function Person(name,age){ this.name = name; this.age = age; } var person1 = new Person('Young',18); console.log(person1.name + ':' + person1.age);
在说优缺点以前,先来讲说她自己的一点小故事吧prototype
function Person(name,age){ this.name=name; this.age=age; this.sayName=function(){ return this.name; } } //当作构造函数使用 var person1 = new Person('Young', 18); person1.sayName(); console.log(person1.name + ':' + person1.age); //当作普通函数调用 Person('Wind', 18); console.log(window.sayName()); //在另外一个做用域中调用 var obj = new Object(); Person.call(obj, 'bird', 100); console.log(obj.sayName());
优势:能够将它的实例标识为一种特定类型code
缺点:每一个方法都要在每一个实例上从新建立一遍。固然你也能够这样改:htm
function Person(name, age){ this.name = name; this.age = age; this.sayName = sayName; } function sayName(){ return this.name; }
改成调用全局函数,这样一来毫无封装性可言。。。接下来的原型模式能够弥补这个的不足对象
function Person(){ } Person.prototype.name = 'Young'; Person.prototype.age = 18; Person.prototype.sayName = function(){ return this.name; } var person1 = new Person(); console.log(person1.sayName()); var person2 = new Person(); console.log(person1.sayName()); alert(person1.sayName === person2.sayName); //person1和person2访问的是同一组属性的同一个sayName()函数
虽然能够经过对象实例访问保存在原型中的值,但却不能经过实例对象重写原型中的值
function Person(){ } Person.prototype.name='Young'; Person.prototype.age=18; Person.prototype.sayName=function(){ return this.name; } var person1=new Person(); var person2=new Person(); person1.name='Wind'; console.log(person1.sayName());//Wind console.log(person2.sayName());//Young alert(person1.sayName==person2.sayName);//true
在咱们调用person1.sayName的时候,会前后执行两次搜索,解析器先肯定实例person1是否有sayName的属性,有则调用本身的属性,没有则搜索原型中的属性。
function Person(){ } Person.prototype.name='Young'; Person.prototype.age=18; Person.prototype.sayName=function(){ return this.name; } var person1=new Person(); var person2=new Person(); person1.name='Wind'; console.log(person1.sayName());//Wind console.log(person2.sayName());//Young delete person1.name; console.log(person1.sayName());//Young console.log(person2.sayName());//Young
使用hasOwnPropertyType方法能够检测一个属性是存在与原型中仍是存在于实例中,该方法是从Object继承来的,实例中为true,原型中为false。
function Person(){ } Person.prototype.name='Young'; Person.prototype.age=18; Person.prototype.sayName=function(){ return this.name; } var keys=Object.keys(Person.prototype); console.log(keys);//["name", "age", "sayName"]
原型模式优缺点
优势:不用每一个方法都要在每一个实例上重申一遍
缺点:不多有人单独使用原型模式地。。问题详列
function Person(){ } Person.prototype={ constructor:Person, name:'Young', age:18, friends:['Big','Pig'], sayName:function(){ return this.name; } }; var p1=new Person(); var p2=new Person(); p1.friends.push('Mon'); console.log(p1.friends);//["Big", "Pig", "Mon"] console.log(p2.friends);//["Big", "Pig", "Mon"]
正是由于实例通常都要有本身的属性,而咱们这里将他放在了Person.prototype中,因此随着p1的修改,整个实例包括原型都修改了。那么,咱们能够组合使用构造函数模式和原型模式。
function Person(name,age){ this.name=name; this.age=age; this.friends=['Big','Pig']; } Person.prototype={ sayName:function(){ return this.name; } }; var p1=new Person('Young',18); var p2=new Person('Wind',78); p1.friends.push('Raganya'); console.log(p1.friends);//["Big", "Pig", "Raganya"] console.log(p2.friends);//["Big", "Pig"] console.log(p1.friends==p2.friends);//false console.log(p1.sayName==p2.sayName);//true
这种模式是目前使用最普遍、认同度最高的一种建立自定义类型的方法。是用来定义引用类型的一种默认模式。