eg:
//定义类
function Person(){}
Person.prototype.name = "licl";
Person.prototype.sayName = function(){
alert(this.name);
}
//实例化
var person1 = new Person();
person1.sayName();//"licl"
var person2 = new Person();
person2.sayName();//"licl"
alert(person1.sayName == person2.sayName);//true
1、理解原型对象、
(1)、只要创建一个新函数,就会为该函数创建一个prototype属性,指向函数的原型对象
(2)、默认情况下,原型对象会自动获得一个constructor(构造函数)属性,这个属性在实例中也是共享的
(3)、这个constructor属性指向prototype属性所在函数
【上例:Person.prototype,construnctor指向Person】
(4)、当创建一个新对象时,新对象内部存在一个指针(内部属性)[[prototype]],指向构造函数的原型对象
(5)、新对象的内部属性[[prototype]],在脚本里没有标准的访问方式,但Firefox、Safari、Chrome中,每个对象上都支持一个proto属性
(6)、isPrototypeOf()方法 ==>确定一个实例对象是否指向一个构造函数
alert(Person.prototype.isPrototypeOf(person1));//true
(7)、Object.getPrototypeOf()方法 == > 返回实例对象的[[prototype]]的值
alert(Object.getPrototypeOf(person1) == Person.prototype);//true
alert(Object.getPrototypeOf(person1).name);//”licl”
【使用这个方法可以方便的获取实例对象的原型,而这个在利用原型实现继承的情况下是非常重要的】
(8)、读取对象时,查找对象值得过程
先在对象实例本身开始查找,找到了,就返回该属性值
在实例对象里找不到,就继续通过[[prototype]]属性找到原型对象,在原型对象里找
(9)、在实例中定义和原型对象中的同名属性,只会屏蔽原型对象中的值,而不会修改原型对象里的属性值
(10)、可以使用delete操作符,删除实例中定义的属性,这样就可以访问原型对象中的同名属性了
person1.name = "ssss";
alert(person1.name);//"ssss"
delete person1.name;
alert(person1.name);"licl"
(11)、hasOwnProperty() ==>检测属性是存在于实例中,还是在原型中,即:当存在于实例中是返回true
alert(person1.hasOwnProperty("name"));//false
peson1.name = "ssss";
alert(person1.hasOwnProoerty("name"));//true
2、使用in操作符
(1)、单独使用in操作符 ==>判断属性在对象是是否存在(不管是在实例中、还是在原型中),存在则赶回true
alert(“name” in person1);//true
alert(“age” in person1);//false
【同时使用hasOwnProperty()方法和in操作符,就可以判断属性是在实例中,还是在原型中了】
function hasPrototypeProperty(object,name){
//返回true,表示属性在原型中,实例中没有
//返回false,没啥意思,可能在实例中有,可能没有这个属性
return !object.hasProperty(name) && (name in object);
}
(2)、for-in循环
(3)、Object.keys() ==>接受一个对象作为参数,返回所有可枚举属性组成的数组
person1.name = “sss”;
person1.age = 12;
Object.keys(person1);//[“name”,”age”];
Object.keys(Person.prototype);//[“name”,”sayName”]
(4)、Object.getOwnPropertyNames() ==>返回所有属性(无论是否可枚举)组成的数组
Object.getOwnPropertyNames(Person.prototype);//[“constructor”,”name”,”sayName”],这里的 constructor是不可枚举的,单也返回了
3、更简单的原型语法
(1)、使用字面量语法定义原型对象的属性
function Person(){};
Person.prototype = {
name:”licl”,
sayName:function(){
alert(this.name);
}
}
但这样子constructor属性就不知想Person了,而是指向Object对象,因为实际上是把prototype重写了
4、原型对象的动态性
实例于原型之间是通过一个指针链接的,所以原型后添加属性,实例也是可以访问的
(前提是这个指针是指向原型对象的,如果原型被重写,就会出问题了,先定义的实例就访问不到属性了,因为指针的指向错了)
5、原生对象的原型(Object,Array,String等)
使用原生对象的原型,不仅可以取得多有默认的方法,还可以自己定义新的方法(很好,但不推荐)
6、缺点:
(1)、省去初始化参数,所有实例在默认情况下,都取相同的属性值
(2)、由于其共享属性的特性,当一个实例修改属性值时,会影响到其他实例的值