原型
在构造函数创建出来的时候,系统会默认帮构造函数创建一个原型对象。
原型的作用:
原型对象中的属性和方法可以被构造函数创建出来的对象访问。
如何访问构造函数的原型:
构造函数.prototyoe
属性(方法)的查找原则:
当访问对象的成员的时候,会在自身找有没有,如果有直接使用,
如果没有找到,则去当前对象的原型对象中找,如果找到了直接使用
如果没有找到,则去原型对象的原型对象中找,如果找到了直接使用
如果没有找到,继续向上查找,直到找到Object.prototype,如果没有属性则是undefined 方法则报错
通过对象访问原型:
_proto_属性(是一个非标准的属性,不推荐使用,主要用来做调试)
在使用新的对象替换掉默认的原型对象之后,原型对象中的constructor属性会变成Object,为了保证原型能正常访问,需要在原型上加一个constroctor 属性指向构造函数
Object.prototype 的成员:
1,constructor
原型对象的一个属性,指向该原型对象相关联的构造函数。
2,hasOwnProperty
用来判断对象本身是否拥有某个属性
3,propertyIsEnumerable
判断属性是否属于对象本身 ,判断属性是否可以被遍历。
4,toString 和 toLocaleString
都是转换成字符串,toLocaleString 是转化成本地的字符串,根据电脑的设置。
5,valueOf
获取当前对象的值
在对象参与运算的时候
1.默认的会先去调用对象的valueOf方法,
2.如果valueOf获取到的值,无法进行运算 ,就去去调用p的toString方法 最终做的就是字符串拼接的工作
6,__proto__
可以使用 对象.__proto__ 去访问原型对象
instanceof 关键字
语法 : 对象 instanceof 构造函数
判断该构造函数的原型是否在该对象的原型链上。
类的声明:
function Animal(){
this.name = 'name'
}
Es6中类的声明
class Animal{
constructor(){
this.name =name;
}
}
实例化
new Animal()
继承:
1,利用构造函数继承
function Parent (){
this.name = 'name'
}
function Child(){
Parent.call(this); //将父级的构造函数this指向子构造函数的对象
this.type = 'type';
}
缺点: 这种构造函数继承,不能够继承父类原型对象上的方法。
2,利用原型链实现继承
function Parent2(){
this.name = 'name';
this.age = 12;
}
function Child2(){
this.type = 'type'
}
Child2.prototype = new Parent2();
var c1 = new Child2();
var c2 = new Child2();
c1.age = 14;
console.log(c2.age ) // true
缺点:只要一个实例改变了父类原型上的属性值,其他的实例也会改变,因为他们共享同一个父类原型。
3,组合方式实现继承
function Parent3(){
this.name ='name'
}
function Child3(){
Parent3.call(this);
this.type ='type';
}
Child3.prototype = new Parent3();
优点:可以有效的避免以上两种继承的问题
缺点:父级的构造函数被执行了两次,实例的constructor 都是父类的构造函数。
4、组合继承的优化
function Parent4(){
this.name ='name'
}
function Child4(){
Parent3.call(this);
this.type ='type';
}
Child4.prototype = Object.create(Parent4.ptototype);
Child4.constructor = Child4;