JavaScript面向对象(二)

原型对象

为什么要使用原型对象?

通过构造函数创建对象的过程中,需要给对象添加方法,这些方法具有相同的代码,只是执行过程不同,但是却占用了不同的内存,也就浪费了内存,随着实例化次数的增加,浪费的内存也就会越来越多;如果将这些方法放在原型对象中,就可以起到共用一块内存的效果,也就是起到了节约内存的作用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Person(name,age){
this.name=name;
this.age=age;
this.say=function(){
alert(this.name);
}
}
var p1=new Person("星爷",20);
p1.say();
var p2=new Person("范爷",16);
p2.say();
var p3=new Person("晨爷",18);
p3.say();
console.log(p1.say==p2.say);//左右两边都是函数,函数也是对象,比较的是内存地址,指向不同的内存,结果为:false
console.log(p1.say.toString());//true——>具有相同的方法体

如何使用原型对象?

  • 任何函数都会有一个prototype属性,该属性的值是一个对象,我们把它称之为原型对象。
  • 给原型对象中添加的属性和方法都可以被构造函数的实例所共享。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function Person(name,age){
this.name=name;
this.age=age;
}
//函数创建好之后,就会拥有一个默认的原型对象,该原型对象就是该函数的prototype属性
Person.prototype.say=function(){
alert(this.name);
};
Person.prototype.run=function(){
alert("5公里越野");
};
//给原型对象中添加一个say方法,就可以让构造函数的实例所共享(实例都可以访问到该方法)
var p1=new Person("冰冰",28);
p1.say();//"冰冰"
p1.run();//"5公里越野"
var p2=new Person("亮亮",10);
p2.say();
p2.run();
console.log(p1.say==p2.say);//true——>指向同样的内存,节约了内存空间
//从2个角度描述原型对象:
//1、构造函数的原型——>构造函数的原型属性——>构造函数的prototype属性
//2、实例的原型——>首先要考虑该实例是由哪个构造函数创建的,指向该构造函数的原型

构造函数/原型/实例三者之间的联系

通过原型图可以很好的帮助我们理解三者之间的关联
js面向对象2/1.png
再从代码上看看有什么关联吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Chinese(name){
this.name=name;
}
var lipi=new Chinese("里皮");
//结论1:函数的原型对象的constructor属性指向函数本身
console.log(Chinese.prototype.constructor===Chinese);//true
//结论2:实例的__proto__属性指向构造函数的原型对象
console.log(lipi.__proto__===Chinese.prototype);//true
//推论1:
console.log(lipi.__proto__.constructor===Chinese);//true
//推论2:
console.log(lipi.constructor===Chinese);//true

对象属性的查找

直接从代码上更直观的了解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//获取对象属性的时候,
// 1、首先查找自身所在的内存,
// 2、然后对象的__proto__原型对象中是否存在该属性,
// 3、再去原型对象的原型对象(__proto__.__proto__)中去查找是否存在该属性,
// 4.。。。。。一直找到原型链的顶端(__proto__:null)
function Student(){
this.name="小红";
}
Student.prototype.say=function(){
};
var s1=new Student();
console.log(s1.name);
console.log(s1.say);
console.log(s1.toString);//s1.__proto__.__proto__.toString
console.log(s1.say2);//undefined一直找到原型链的顶端都找不到say2属性,所以认为无法访问
console.log(s1.__proto__.__proto__.__proto__);//null
//s1.__proto__——>Student.prototype——>s1继承自Student.prototype这个对象的
//s1.__proto__.__proto__——>Object.prototype——>Student.prototype继承自Object.prototype对象的

×

可以的话,我想喝杯咖啡续命

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 原型对象
    1. 1.1. 为什么要使用原型对象?
    2. 1.2. 如何使用原型对象?
    3. 1.3. 构造函数/原型/实例三者之间的联系
    4. 1.4. 对象属性的查找