参考解释:
构造函数与实例对象
关系:
实例对象是通过构造函数来创建的,创建的过程叫实例化。
示例代码:
//1.自定义构造函数 function Person(name,age){ // 当使用 new 操作符调用 Person() 的时候,实际上这里会先创建一个对象 // var instance = {} // 然后让内部的 this 指向 instance 对象 // this = instance // 接下来所有针对 this 的操作实际上操作的就是 instance this.name=name this.age=age this.play=function(){ console.log('play games') console.log(this.name) } // 在函数的结尾处会将 this 返回,也就是 instance // return this }
//2.创建对象 let per = new Person('小白',10) per.play()
console.dir(per)//输出实例对象 //Person console.dir(Person)//输出构造函数 //ƒ Person(name,age) console.log(per.constructor)//per这个实例对象的构造器(构造函数) /* *ƒ Person(name,age){ * this.name=name * this.age=age * this.play=function(){ * console.log('play games') * } *} */
//判断对象具体类型的两种方法 console.log(per.constructor===Person)//true console.log(per instanceof Person)//true //一个实例对象的构造器不一定是自己的构造器,有可能是Object;因此推荐第二种方法
(1)1到2的过程就叫实例化对象的过程,即对象实例化
(2)per这个对象的构造函数就是Person
原型对象
__proto__与prototype
console.log(per.__proto__.constructor===Person)//true console.log(per.__proto__.constructor===Person.prototype.constructor)//true
关于构造函数内存浪费的问题,通过原型添加方法解决,实现数据共享
function Person(name,age){ this.name=name this.age=age this.play=function(){ console.log('play games') } this.say=function(){ console.log('hi') } } let per1=new Person('小白',10) let per2=new Person('小黄',8) per1.play() per2.play() console.log(per1.play === per2.play) //false 指向不同的空间,其中的内容一样,内存浪费 //原型添加方法解决数据共享 function Person(name,age){ this.name=name this.age=age } Person.prototype.play=function(){ console.log('play games') } Person.prototype.say=function(){ console.log('hi') } //==可写成== function Person(name,age){ this.name=name this.age=age } Person.prototype={
constructor:Student, play:function(){console.log('play games')}, say:function(){console.log('hi')} } let per1=new Person('小白',10) let per2=new Person('小黄',8) per1.play() per2.play() console.log(per1.play === per2.play) //true 指向同一空间,内存节省
对原型对象的理解:
实例对象中,有__proto__属性,也是对象,称为原型,不是标准的属性,浏览器使用,IE8不支持
构造函数中,有prototype属性,也是对象,称为原型,是标准属性,程序员使用
__proto__和prototype都是原型对象
原型作用之一:实现数据共享,节省空间
构造函数、实例对象、原型对象之间的关系
解释理解:
构造函数有prototype属性(先这么理解),即为原型对象;
原型对象中的constructor构造器就是构造函数本身;
构造函数创建实例对象;
实例对象中有__proto__属性(先这么理解);
__proto__共用构造函数prototype中的方法
代码示例
总结
1.构造函数可以实例化对象
2.构造函数中有一个属性:prototype,是构造函数的原型对象
3.构造函数的原型对象(prototype)中有一个cunstructor构造器,这个构造器指向的就是自己所在的原型对象所在的构造函数
4.实例对象的原型对象(__proto__)指向的是该构造函数的原型对象,prototype中的方法共享给实例对象
5.原型对象中的添加的方法可以相互调用
6.实例对象使用的属性或方法,先在实例中查找,找到了则直接使用,找不到则去实例对象的__proto__指向的原型对象prototype中找,找到则使用,找不到则报错。示例代码:
补充:
原型指向可以改变
function Per (age){ this.age=age } Per.prototype.say=function(){ console.log('say111') } function Stu(){ } Stu.prototype.eat=function(){ console.log('eat111') } Stu.prototype = new Per(10) let stu = new Stu() stu.say() //say111
理解:
实例对象的原型__proto__指向的是该对象所在的构造函数的原型对象prototype;
构造函数的原型的指向改变了,实例对象的原型的指向也会跟着构造函数的原型的指向发生改变(人家是一条链上的);
实例对象和原型对象是通过__proto__联系起来的。
待补充待补充待补充......