问题:在构造方法中,如果重复执行,会造成多个对象有多个方法副本,影响性能,造成内存浪费。若将方法放到外面,在开发中自定义成员越多,出现命名重复的几率很大,而且会有安全隐患。如:
function Person(){
this.sayHello()=function(){};
}
由于对象调用Person()创建出来,因此一个对象在创建时,函数sayHello都会被创建,那么每个对象都有一个独立的,不同的但是功能和逻辑相同的函数,这样就会消耗性能,浪费内存,则需要把函数放到构造函数外,那么在构造函数中只需要引用函数即可。
1.原型
什么是?
为了解决以上问题,每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,将共享的方法和属性放到这个对象中,这个对象就是我们所说的原型,称为函数的原型属性,使用函数.prototype引用。每个由该构造函数创建的对象,都会默认链接到这个对象上,在该对象访问某一方法或属性时,若该对象中没有,就会到这个 对象中查找
构造函数、原型、由构造函数创建出来的对象的关系
1.原型对于构造函数,称为原型属性
2.原型针对于构造函数创建出来的对象称为原型对象
3.构造函数创建出来的对象继承自该对象的原型对象
4.原型中的成员,可以直接被实例对象使用,这样的继承称为原型继承
关于prototype、proto 、constructor
1.prototype:只作用于函数,无法被对象直接 引用
2._pro _:每个被创建出来的对象都具有的属性,指向该对象的原型(即XX.prototype==AA._pro _),在实例化对象(构造函数)时,找某个属性,在当前属性中无法找到属性,会从xxx.__proto__中进行寻找。
注:_pro _可以访问原型,但是在开发中,尽量避免使用实例去改变原型成员,但是在调试中使用非常方便,可以轻易访问原型进行查看成员
3.constructor:是原型中的属性,指向构造函数(Person.prototype.constructor=Person)
注:当直接替换修改原型时,原型的指向发生了改变,新增的对象默认没有constructor属性,所以使用替换方法修改原型时,一般会添加constructor属性
三者关系图:
Object.create():
功能:实现继承,创建一个原型继承自参数对象,返回的新对象,原型就是参数中表示的对象
var o={
sayHello:function(){
console.log('你好');
}
}
var o1=Object.create(o);
//创建一个对象o1,该对象的原型即_proto_就是o
2.原型链
***什么时?***凡是对象都有原型,原型也是对象,因此,凡是给定一个对象就可找到他的原型,原型还有原型,如此下去,就构成原型链;
原型链结构
1.默认结构:凡是使用构造函数创建出来的对象,并且没有利用赋值的方式修改原型,就说该对象保留默认的原型链。
function Person(){}
var p=new Person();
p具有默认的原型链:p->Person.prototype->Object.prototype->null
另外:
*1.默认的原型链结构:
当前对象->构造函数.prototype->Object.prototype->null
*{}的原型链:
当前对象->Object.prototype->null
*[]的原型链:
当前对象->Array.prototype->Object.prototype->null
2.默认原型链改变:
在现实继承中的时候,有时会利用替换原型链结构的方式实现原型继承,那么原型链结构就会发生改变
function ItCaseCollection(){};
ItCaseCollection.prototype=[];
var arr=new ItCaseCollection();
//原型链为:
//arr->[]->Array.prototype->Object.prototype->null