当前位置:网站首页>原型与原型链
原型与原型链
2022-07-07 08:19:00 【王元肉】
文章目录
构造函数
什么是构造函数
构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员对象初始化值,它总与new搭配使用。把对象的一些共有的属性和方法放在这个构造函数里面。
构造函数的注意事项
构造函数应该:
- 首字母要大写
- 和new搭配使用
创建对象的三种方式
- 对象字面量
const obj = {
}
- new Object
const obj = new Object();
- 自定义构造函数
const Star = function(uname,age){
this.uname = uname;
this.age = age;
this.sing = function(){
console.log('唱歌');
}
}
const ldh = new Star('刘德华',18);
new关键字的作用
在实例化对象的时候,会按顺序执行下面的步骤:
- 在内存中开辟一个新的空对象
- 让this指向这个新的对象
- 执行构造函数里面的代码,将属性和方法添加给新的对象
- 返回这个对象
静态成员和实例成员
静态成员:在构造函数本身上添加的就是静态成员,能够通过构造函数本身才能访问
实例成员:在构造函数中,使用this添加的就是实例成员,能够通过实例对象才能访问
function Star(uname,age){
//uname,age,sing都是实例成员
this.uname = uname;
this.age = age;
this.sing = function(){
console.log('唱歌');
}
}
var ldh = new Star('刘德华',18);
// xb就是静态成员
Star.xb = 'na';
console.log(Star.xb);//na
console.log(ldh.xb);//undefined
console.log(ldh.uname);//刘德华
console.log(Star.uname);//undefined
为什么使用原型
构造函数存在浪费内存的问题:构造函数中的方法是通过函数来实现的,函数再声明使用的时候会开辟一块内存空间,因此,我们每使用构造函数实例化一个对象,对象都会为方法函数开辟一块内存空间并指向它,但是其实这些内存空间存放的东西是一样的,这就造成了内存空间的浪费。
const Star = function(uname,age){
this.uname = uname;
this.age = age;
this.sing = function(){
console.log('唱歌');
}
}
const ldh = new Star('刘德华',18);
const zxy = new Star('张学友',18);
console.log(ldh.sing === zxy.sing);//false
//ldh和zxy两个实例对象的方法是不相等的false
构造函数的原型对象prototype
JavaScript规定,每一个构造函数中都有一个prototype属性,它的属性值是一个对象,并且这个对象里面的属性和方法都会被构造函数所拥有,这个对象就是原型对象。通常我们把共有的属性直接定义在构造函数上面,把方法定义在构造函数的prototype属性对应的原型对象上面,可以节省内存空间,如果方法放在构造函数中,每次实例化一个对象都要开辟一块空间存储方法,这些方法都是一样的,浪费空间。因此,我们知道构造函数中的原型对象的作用就是共享方法
const Star = function(uname,age){
this.uname = uname;
this.age = age;
}
Star.prototype.sing = function(){
console.log('唱歌');
}
const ldh = new Star('刘德华',18);
ldh.sing(); // 唱歌
const zxy = new Star('张学友',19);
zxy.sing(); // 唱歌
console.log(ldh.sing === zxy.sing); // true
对象身上的原型对象__proto__
每个对象中都会有一个属性__proto__,它的属性值就是构造函数的prototype属性的属性值(也是一个对象 ),之所以实例化的对象可以使用构造函数prototype的属性和方法,就是因为__prpto__的存在,__proto__对象原型和原型对象prototype是等价的。
__proto__的意义在于系统查找对象,它是一个非标准的属性,因此实际开发中我们不可以使用这个属性。
const Star = function(uname,age){
this.uname = uname;
this.age = age;
}
Star.prototype.sing = function(){
console.log('唱歌');
}
const ldh = new Star('刘德华',18);
console.log(ldh.__proto__ === Star.prototype);//true
javascript访问对象的属性和方法的顺序规则
首先查找对象本身上有没有
查找它的原型__proto__上有没有,同理也是构造函数的prototype的原型对象
再查找第2步查找到的原型对象身上有没有,一直找到Object原型对象身上的__proto__
如果前3步都没有找到,那就是null
整个过程靠的是__proto__这个属性,提供了查找的“路线”,我们称为“原型链”。
const Star = function(){
};
Object.prototype.sing = function(){
console.log("Obj唱歌");
};
const ldh = new Star();
ldh.sing(); // Obj唱歌
const Star = function(){
};
Object.prototype.sing = function(){
console.log("Obj唱歌");
};
Star.prototype.sing = function(){
console.log("唱歌");
};
const ldh = new Star();
ldh.sing(); // 唱歌
const Star = function(){
this.sing = function(){
console.log("ldh唱歌");
}
};
Object.prototype.sing = function(){
console.log("Obj唱歌");
};
Star.prototype.sing = function(){
console.log("唱歌");
};
const ldh = new Star();
ldh.sing(); // ldh唱歌
原型对象身上的constructor属性
const Star = function(uname,age){
this.uname = uname;
this.age = age;
}
Star.prototype.sing = function(){
console.log('唱歌');
}
//这种形式就是将原型对象重新赋值,Star.prorotype.constructor 就不是Star构造函数了
Star.prototype = {
constructor: Star,
eat: function(){
console.log('吃饭');
},
sleep: function(){
consolo.log('睡觉');
}
}
//constructor这个属性的值就是用来记录该原型对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数
const ldh = new Star('刘德华',18);
ldh.eat();//吃饭
ldh.sing();//Uncaught TypeError: ldh.sing is not a function
//ldh的原型对象被修改了
构造函数、原型对象、实例对象之间的关系图示
原型链图示
原型this的指向问题
构造函数中this指向的是实例对象
原型对象函数中this指向的也是实例对象
var that1;
var that2;
function Star(uname,age){
this.uname = uname;
this.age = age;
that1 = this;
}
Star.prototype.sing = function(){
console.log('唱歌');
that2 = this;
}
console.log(that1 == that2);//true
原型链的应用–继承
// 继承属性:
// 就是用call()把父类的this指向改为子类的this指向
// 具体操作示范:
function Father(uname,age){
this.uname = uname;
this.age = age;
}
Father.prototype.money = function(){
console.log('我现在可以挣钱');
}
function Son(uname,age,score){
//通过调用call这个方法就可以继承父类构造函数中所有的属性,简洁了代码
Father.call(this,uname,age);
this.score = score;
}
var son = new Son('刘德华',18,100);
console.log(son);
// {
// "uname": "刘德华",
// "age": 18,
// "score": 100
// }
// 继承方法:
/* 修改子类的原型对象prototype为new Father()这个实例,通过原型链__proto__就继承了父类的原型对象以及其中的方法;但是不要忘记用Son.prototype.constructor = Son;指回原来的构造函数,这是这个实例对象的“身份证”,说明它是哪个构造函数实例化出来的 */
function Father(uname,age){
this.uname = uname;
this.age = age;
}
Father.prototype.money = function(){
console.log('我现在可以挣钱');
}
function Son(uname,age,score){
//通过调用call这个方法就可以继承父类构造函数中所有的属性,简洁了代码
Father.call(this,uname,age);
this.score = score;
}
Son.prototype = new Father();
Son.prototype.constructor = Son;
Son.prototype.kaoshi = function(){
console.log('考试');
}
var son = new Son('刘德华',18,100);
console.log(son);
// {
// "uname": "刘德华",
// "age": 18,
// "score": 100
// }
son.money(); // 我现在可以挣钱
son.kaoshi(); // 考试
边栏推荐
- @Transcation的配置,使用,原理注意事项:
- 1324:【例6.6】整数区间
- 【acwing】786. Number k
- Some properties of leetcode139 Yang Hui triangle
- HAL库配置通用定时器TIM触发ADC采样,然后DMA搬运到内存空间。
- Inno setup packaging and signing Guide
- High number_ Chapter 1 space analytic geometry and vector algebra_ Quantity product of vectors
- Study summary of postgraduate entrance examination in November
- .NET配置系统
- AHB bus in stm32_ Apb2 bus_ Apb1 bus what are these
猜你喜欢
Leetcode exercise - 113 Path sum II
【剑指Offer】42. 栈的压入、弹出序列
PDF文档签名指南
对word2vec的一些浅层理解
1324:【例6.6】整数区间
Talking about the return format in the log, encapsulation format handling, exception handling
LLVM之父Chris Lattner:為什麼我們要重建AI基礎設施軟件
High number_ Chapter 1 space analytic geometry and vector algebra_ Quantity product of vectors
The method of word automatically generating directory
[ORM framework]
随机推荐
Postman interface test IV
Fiddler break point
Word自动生成目录的方法
. Net configuration system
Factorial implementation of large integer classes
对存储过程进行加密和解密(SQL 2008/SQL 2012)
JMeter about setting thread group and time
反射效率为什么低?
对word2vec的一些浅层理解
基于HPC场景的集群任务调度系统LSF/SGE/Slurm/PBS
Use the fetch statement to obtain the repetition of the last row of cursor data
1321:【例6.3】删数问题(Noip1994)
电表远程抄表拉合闸操作命令指令
STM32 ADC and DMA
JMeter installation
The request object parses the request body and request header parameters
Multisim--软件相关使用技巧
Inno setup packaging and signing Guide
P2788 数学1(math1)- 加减算式
[email protected]能帮助我们快速拿到日志对象