一,函数的prototype是一个对象属性,(准确来说,这个属性是指向一个对象的指针)
Person.prototype.LEGS_NUM=2; function Student(name,age,className){ Person.call(this,name,age); this.className=className; } Student.prototype=Object.create(Person.prototype); Student.prototype.hi=function(){ console.log("Hi,name is "+this.name+",year is "+ this.age+",class is "+this.className+"."); } var bosn=new Student("Bosn",12,"class2"); bosn.hi(); console.log(bosn.LEGS_NUM); var amier=new Person("Amier",24); amier.hi();
function foo(){
this.y="y";
}
console.log(typeof foo.prototype);//object
function foo(){
this.y="y";
}
foo.prototype.x=1;
var obj=new foo();
console.log(obj.x);//对象原型的属性,也就是foo.prototype的x属性
console.log(obj.y);//对象的属性,在函数foo调用时被复制
foo.prototype如下:
foo.prototype.__proto__会指向Object.prototype(Chrome下) (注意总共4个_)
二,重点:prototype(是指针)是一个函数的对象属性,当用构造器构造一个对象时,这个对象的原型就是这个构造器的prototype属性;
三,Object.create(参数)可以拿到原型是传入参数的空对象;student的实例的原型是student.prototype,而student.prototype的原型是person.prototype
但有个不太明白的地方:
student.prototype=Object.create(person.prototype);
student.prototype=person.prototype;//就算指向同个对象,为什么改变student.prototype会改变person.prototype,它们指向共同的对象又是什么(
object吗);
四,继承实例
function Person(name,age){
this.name=name;
this.age=age;
}
Person.prototype.hi=function(){
console.log("Hi,name is "+this.name+",year is "+
this.age);
}
function foo(){}
foo.prototype.z=3;
var obj=new foo();
console.log('z' in obj);//true 判定的是在对象和原型链上的属性
console.log(obj.hasOwnProperty)//false 判定的是对象上的属性,不包括原型链
Person.prototype.LEGS_NUM=2; function Student(name,age,className){ Person.call(this,name,age); this.className=className; } Student.prototype=Object.create(Person.prototype); Student.prototype.hi=function(){ console.log("Hi,name is "+this.name+",year is "+ this.age+",class is "+this.className+"."); } var bosn=new Student("Bosn",12,"class2"); bosn.hi(); console.log(bosn.LEGS_NUM); var amier=new Person("Amier",24); amier.hi();
原型链图示:
在调用对象方法时,首先会看这个对象是否有这个方法,如果没有,则会随原型链向上查找。
细节:1.并不是所有对象的原型链上都有Object.prototype,比如var obj2=Object.create(null);
2.bind方法返回的函数可能没有prototype属性;
五,如何返回原型
var obj={x:1};
console.log(obj.__proto__===Object.prototype);//true chrome
console.log(Object.getPrototypeOf(obj)===Object.prototype);//true es5
六,如果改变prototype会怎样
function Student(){}
Student.prototype.x=1;//注意prototype是指针
var bosn=new Student();//它的原型是Student.prototype指向的对象
console.log(bosn.x);
Student.prototype={x:2};//改变prototype这个指针
console.log(bosn.x);//bosn的原型还是原来的对象
var amier=new Student();
console.log(amier.x);//它的原型是另一个对象
//输出1,1,2
七,编辑效应
为了兼容不支持es5的浏览器,有时需要向内置对象的prototype添加属性。这时为了产生编辑效应,不应该使用Object.prototype.x,这样的x属性会被枚举 而应该Object.definePorperty();
Object.defineProperty(Object.prototype,'x',{writable:true,value:1});
//设置writable间接使它不可枚举
var obj={};
console.log(obj.x);
for(var key in obj){
console.log('result:'+key);
}
//没有任何输出
function foo(){}
foo.prototype.x=1;//一般构造器或内置构造器用这样的方法新加的prototype.x会被枚举
var obj=new foo();
console.log(obj.x);
for(var key in obj){
console.log('result:'+key);
}
//1 result:x
八,判定一个变量是否是个方法
function foo(){}
var obj=new foo();
console.log(typeof obj.toString);
九,判断属性是否在对象和原型链上
function foo(){}
foo.prototype.z=3;
var obj=new foo();
console.log('z' in obj);//true 判定的是在对象和原型链上的属性
console.log(obj.hasOwnProperty('z'))//false 判定的是对象上的属性,不包括原型链