第六章-面向对象到程序设计
6.1
第5章创建对象 var person a=new object(); person.name="Nicholas";person.age=29;person.job="software engineer";person.sayName=function(){alert(this.name)};//这种发法到缺点是使用同一个接口创建很多对象,产生大量重复代码,为了解决这个问题人们工厂模式的一个变体。
6.1.1 工厂 模式 (解决了创建多个对象到问题,但是无法解决识别对象到问题<即怎样知道一个对象的类型,因此6.1.2>)
function cratePerson(name,age,job){
var o=new object();
o.name=name; o.age=age; o.job=job; o.sayName=function(){alert(this.name);};
returen o;
}
var person1=createPerson("Nicholas",39,"software engineer"); person1.sayName();
var person2=createPerson("Grey",29,"Doctor"); person2.sayName()
6.1.2 构造函数模式
function Person(name,age,job){//Person构造函数首字母大写,其他非构造函数到函数首小写
this.name=name;this.age=age;this.job=job;this.sayName=function(){alert(this.name);};
}//没有显示创建对象;直接将属相和方法赋给this;没有ruturn;
var person1=new Person("Nicholas",20,"software engineer");person1.sayName();
var person2=.......;person2.sayName();
//这两个函数都有个constructor属性,该属性指向Person。例如:alert(person1.constructor==Person);//true alert(person2.constructor==Person);//true;
对象constructor属性,最初是用来标示对象类型的,但是,用来检测对象类型,还是instanceof操作根尖可靠,我们在这个例子中创建的对象,即使Object实例,又是Person实例。alert(person1 instanceof object);//true alert(person1 instanceof Person)//true;
//构造函数意味着将来可以将它到实例表示为一种特定到类型,这是构造函数模式胜过工厂模式到地方!!
//构造函数于非构造函数到区别主要是new关键字,其他并无区别,例如:
var person =new Person("Nicholas",29,"software engineer");
person.sayName();//Nicholas;
//作为普通函数
Person("Nicholas",28,"software engineer");//添加到window
window.sayName();//Nicholas;
//在另一个对象到作用域中调用
var o=new object();
Person.call(o,"kristen",25,"Nurse");//将Person方法放到o中
o.sayName();
2.构造函数到问题
构造函数模式虽然好,但并非没有缺点,问题就是,每个方法都要在每个实例上创建一遍,person1到syaName()于person2到sayName()是不同到方法,例如:
alert(person1.sayName==person2.sayName);//false
也可以将sayNameI 方法,提取到全局 变量中,但是这样每个全局方法,只能用于某个对象,如果一个对象很多全局函数,我们这个自定义的引用类型就毫没有封装可言了。
6.1.3 原型模型
我们创建到每个函数都有个prototype(原型)属性,这个属性是一个对象,她的用途是,包含所有特定类型到所有实例共享到属性和方法。使用prototype到好处就是可以让所有对象实例共享他所包含到实例和方法。
function Person(){}
Person.prototype.name="Nicholas";
Person.prototype.age=23;
Person.prototype.job="software engineer";
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 比较两个方法会发现,他们是相等的;
每个原型模型实例(person1、person2),都有一个_proto_属性这个属性指向 Person到Prototype属性
可以功过isPrototypeOf()来确定对象之间是否有这种关系,因为每个对象到_proto_指向调用isPrototypeOf方法的对象(Person.Prototype),那么,
alert(Person.prototype.isPrototypeOf(person1));//true
alert(Person.prototype.isPrototypeOf(person2));//true
原型模型,遍历,首先会遍历,在实例调用时,首先遍历,实例有没有该方法,或属相,如没有再去找原想中遍历调用,实例记录了自己到属相方法,调用时没有才去调用原型
function Person(){}
Person.name="Nicholas";
Person.age=32;
Person.sayName=function(){alert(this.name);};
var person1=new Person(); //person1.name="Grey"; alert(person1.name);//Grey
var person2=new Person(); alert(person2.name); //Nicholas
delete person1.name;//删除person1自己到name 属性
alert(person1.name);//Nicholas
也可用实例的hasOwnProperty()方法检测是否实例是否拥有自己到模个属性。
person1.name="Grey";
alert(person1.hasOwnProperty("name"));//true
delete person1.name;
alert(person1.hasOwnProperty("name"));//false
2.原形与in操作符
alert(name in person1);//true