前言
通过上一篇博客我们主要了解了一些JavaScript中关于ES6的面向对象语法、类的继承以及原型对象的相关知识和概念,接下来我们将会对这些知识进行更深层的学习及探究。
一、 什么是构造函数的原型对象?
1、什么是构造函数?
要想了解什么是构造函数的原型对象,就要先了解什么是构造函数。构造函数的作用是新建实例对象,并且给实例对象内的成员(属性或方法)赋值。
使用方法:
function Animals(name){
this.name = name
this.eat = function(){
console.log(this.name+'在吃东西')
}
}
var a1 = new Animals('熊猫')
a1.eat()
console.log(a1.name)//输出结果为熊猫
2、什么是构造函数原型对象?
简单来说就是我们创建的每个构造函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。即:通过调用构造函数而创建的那个对象实例的原型对象。
例如:
function Football(name){
this.name = name
this.show = function(){
console.log('球队名:',this.name)
}
}
Football.prototype.ecl = function(){原型对象作用:可以共享方法.sayHello(),开辟了一个新的地址空间所有对象可以共享
console.log('hello,欧冠')
}
var fb = new Football('皇家马德里')
var fb1 = new Football('利物浦')
let flag = (fb.ecl() === fb1.ecl())//全类型,判断值和地址是否相等
console.log(flag)
let flag2 = (fb.show === fb1.show)
console.log(flag2)//false,地址不等
效果:
在上面这段代码中可以看到在使用ecl
的两个对象在进行判断后输出为ture,就可以知道原型对象的共享方法。这样做就可以在一定程度上节省内存,避免造成内存的浪费。
二、什么是对象的原型对象?
每个对象都有一个原型对象,通过__proto__
访问。构造方法的原型对象和由该构造方法创建的对象的原型对象是相等的(一样的)。
例如:
function Person(name){
this.name = name
this.show = function (){
console.log('姓名:',this.name)
}
}
Person.prototype.sayhello = function (){
console.log('HELLO')
}
//输出Person的原型对象
//console.log(Person.prototype)//在node中输出的是:{} ,在浏览器的控制台输出:{constructor: ƒ}
var p1 = new Person('老虎')
var p2 = new Person('章鱼')
/* let flag = (p1.sayhello == p2.sayhello)
console.log(flag)
let flag2 = (p1.show == p2.show)
console.log(flag2) */
//输出p1对象的原型对象
console.log(p1.__proto__ )
console.log(p1.__proto__ === Person.prototype)//输出为;true
实例对象与原型对象的关系如下图:
三、什么是原型对象的原型对象
原型对象本身也是一个对象,所以它也有自己的原型对象
(1)获取原型对象的原型对象: 构造方法名.prototype.__proto
(2)原型对象的原型对象构造方法:构造方法名.prototype.__proto.constructor
例如:
let stu = {}
function stu1(){}
//console.log(stu.constructor)
//输出原型对象的原型对象
console.log(stu1.prototype.__proto__)//[Object:null prototype]{}
//输出原型对象的原型对象的构造方法
console.log(stu1.prototype.__proto__.constructor)//[Function:Obejct]
原型对象的原型对象之间关系如下图:
四、如何通过原型链来实现类的继承
1、什么是原型链
原型链通俗易懂的理解就是可以把他想象成一个链条,互相连接成一整串链子。严谨的说就是每个构造函数都有原型对象,每个构造函数实例都包含一个指向原型对象的内部指针(proto),如果我们让第一个构造函数的原型对象等于第二个构造函数的实例,结果第一个构造函数的原型对象将包含一个指向第二个原型对象的指针,再然第三个原型对象等于第一个构造函数的实例,这样第三个原型对象也将包含指向第一个原型对象的指针,以此类推,就够成了实例于原型的链条,这就是原型链的基本概念。
2、原型链的结构图:
2.1、原型链的结构图
2.2、ES5中实现原型链类的继承
//通过原型链来继承
//1、定义父类构造方法
function SuperType(){
this.property = '中国人民银行'
}
//2、给supertype的原型对象增加方法
SuperType.prototype.getSuperValue = function(){
return this.property
}
//3、定义子类构造方法
function SubType(){
this.subProperty = '招商银行'
}
//4、实现子类对父类的继承
SubType.prototype = new SuperType()//通过原型对象实现子类对父类的继承
//5、在子类的原型对象上增加一个方法
SubType.prototype.getSubValue = function(){
return this.subProperty
}
SubType.prototype.getSuperValue = function(){
return '中国银行'
}
//6、创建一个子类的实例对象
let sub = new SubType()
console.log(sub.getSuperValue())
console.log(sub.getSubValue())//子类的实例对象调用父类的方法
效果: