原型 prototype
- JS规定每一个构造函数都有一个prototype属性,指向另一个对象,称为原型对象
- 构造函数通过原型分配的函数时所有对象所共享的
- 这个对象可以挂载函数,对象实例化不会多次创建原型啥办法函数,节约内存
- 可以把不变不变的方法直接定义在prototype对象上,不定义在构造函数里。这样所有对象的实例就可以共享这些方法
- 每个原型对象里都有constructor属性,该属性指向该原型对象的构造函数。
- 构造函数和原型对象中的this都指向实例实例化对象
//JS规定每一个构造函数都有一个prototype属性,指向另一个对象,称为原型对象
<script>
function Employee(uername, age) {
this.uername = uername
this.age = age
}
//把不变不变的方法直接定义在prototype对象上
Employee.prototype.hobby = function(){
console.log('爱好特别多');
}
console.dir(Employee.prototype)
const people = new Employee('小王',16)
所有对象的实例就可以共享这些方法
people.hobby()
</script>
constructor(构造函数)
每个原型对象里都有constructor属性,该属性指向该原型对象的构造函数,但是如果有多个对象的方法,可以给原型对象采取对象形式赋值,但是这样会覆盖构造函数原型对象原来的内容,修改后的原型对象constructor就不在指向当前的构造函数了,可以在修改后的原型对象中添加一个constructor指向原来的构造函数。
<script>
function Employee(uername, age) {
this.uername = uername
this.age = age
}
console.log(Employee.prototype);
Employee.prototype = {
constructor:Employee,
sing : function (){
console.log('爱唱歌')},
live : function (){
console.log('爱生活')},
}
console.log(Employee.prototype);
对象原型 __ proto__
对象都会有一个属性 proto 指向构造函数的prototype原型对象,之所以对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有对象原型 proto 原型的存在.
原型继承
<script>
let Employee = {
like : 'play',
Skill : 'lazy'
}
// 1.创建构造函数
function People (){}
// 2.构造函数的原型是Employee 通过原型继承Employee
People.prototype = Employee
const xh = new People()
// 3.xh是People的实例对象.通过对象原型就可以访问到原型.
console.log(xh);
console.log(People.prototype);
console.log(xh.__proto__);
</script>
原型继承的问题
<script>
let Employee = {
like : 'play',
Skill : 'lazy'
}
// 1.创建构造函数
function People (){}
// 2.构造函数的原型是Employee 通过原型继承Employee
People.prototype = Employee
const xh = new People()
People.prototype.sing = function () {
console.log('唱歌');
}
console.log(xh);
// -------------------------------------
function Alien() {
}
Alien.prototype = Employee
const wxr = new Alien()
console.log(wxr)
// 当通过原型给people添加一个方法,那么people的实例对象身上就会找到这个方法sing,
// 但是发现在Alien的实例对象wxr上也能找到方法sing
</script>
原因:如上图所示Alien.prototype = Employee和People.prototype = Employee指向同一个Employee对象,当其中一个给予修改则另一个也会受到影响
改进方法
因为每次new出的实例对象只是结构相同new产生的对象是唯一的都不相同,那么添加方法就不会影响到其他的实例对象.
原型链
- 当访问一个对象的某个属性时,会先在这个对象本身属性上查找
- 如果没有找到,则会去它的
__proto__隐式原型上查找,即它的构造函数的prototype - 如果还没有找到就会再在构造函数prototype的
__proto__隐式原型中查找 - 直到构造函数原型对象prototype的
__proto__隐式原型指向为null就停止 - 这样一层一层向上查找就会形成一个链式结构,我们称为原型链。
看图