原型
- 在 JavaScript 中,每个对象都有一个内部属性
[[Prototype]]
,它指向该对象的原型,可以通过 对象名.__proto__ 或 Object.getPrototypeOf(对象名) 访问对象的原型对象 - 原型是一个对象,它包含可被共享和继承的属性和方法。
- 对象可以通过原型访问属性和方法,如果对象本身没有定义某个属性或方法,它会沿着原型链向上查找,直到找到该属性或方法或者到达原型链的末尾。
原型链
- 原型链是由对象之间的原型引用所组成的链式结构。
- 当我们访问一个对象的属性或方法时,如果该对象本身没有定义,JavaScript 引擎会沿着原型链向上查找,直到找到该属性或方法或者到达原型链的末尾(即 Object.prototype)。
- 原型链的顶端是 Object.prototype,它是所有对象的默认原型
原型链的调用机制
/**
* 原型链
*/
function Dq(){
this.constructor.prototype.dq = () => console.log('地球');
this.constructor.prototype.some = () => console.log('Dq-Same');
}
function Zg(){
this.init = function(){
const dq = new Dq();
Object.setPrototypeOf(this.constructor.prototype, dq.__proto__)
this.constructor.prototype.constructor = this.constructor
}
this.init()
this.constructor.prototype.zg = () => console.log('中国');
this.constructor.prototype.some = () => console.log('Zg-Same');
}
function Gd() {
this.init = function(){
const zg = new Zg();
Object.setPrototypeOf(this.constructor.prototype, zg.__proto__)
this.constructor.prototype.constructor = this.constructor
}
this.init()
this.constructor.prototype.gd = () => console.log('广东');
this.constructor.prototype.some = () => console.log('Gd-Same');
}
function Gz() {
this.init = function(){
const gd = new Gd();
Object.setPrototypeOf(this.constructor.prototype, gd.__proto__)
this.constructor.prototype.constructor = this.constructor
}
this.init()
this.constructor.prototype.gz = () => console.log('广州');
this.constructor.prototype.some = () => console.log('Gz-Same');
}
function Person() {
this.init = function(){
const gz = new Gz();
Object.setPrototypeOf(this.constructor.prototype, gz.__proto__)
this.constructor.prototype.constructor = this.constructor
}
this.init()
this.constructor.prototype.person = () => console.log('人');
this.constructor.prototype.some = () => console.log('Person-Same');
}
function Man(name){
this.name = name;
this.init = function(){
const pr = new Person()
Object.setPrototypeOf(this.constructor.prototype, pr.__proto__)
this.constructor.prototype.constructor = this.constructor
}
this.init()
this.constructor.prototype.man = () => console.log('男');
this.constructor.prototype.some = () => console.log('Man-Same');
}
const p1 = new Man('刘德华')
console.log(p1);
//刘德华
console.log(p1.name);
//男
p1.man()
//人
p1.person()
//广州
p1.gz()
//广东
p1.gd()
//中国
p1.zg()
//地球
p1.dq()
//ture 执行的是同个原型对象
console.log(p1.__proto__ === Object.getPrototypeOf(p1));
//p1对象没有some()方法找原型对象
//Man-some
p1.some()
//p1原型对象的some()方法
//Man-Same
p1.__proto__.some()
//true
//证明p1.some()实际上调用的是p1.__proto__.some()
console.log(p1.some === p1.__proto__.some);
//Person-Same
p1.__proto__.__proto__.some()
//false
console.log(p1.some === p1.__proto__.__proto__.some)
//Gz-Same
p1.__proto__.__proto__.__proto__.some()
//Gd-Same
p1.__proto__.__proto__.__proto__.__proto__.some()
//Zg-Same
p1.__proto__.__proto__.__proto__.__proto__.__proto__.some()
//Dq-Same
p1.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__.some()
//Error
p1.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__.some()
console.log('----------------------------------------------------------------');
//通过递归的方式输出
const outSome = (obj) => {
//判断对象是非空
if(!obj){
return
}
/**
* 判断对象的原型是不是指向Object.prototype
* 因为Object.prototype里面没有定义some()方法
*/
if(obj.__proto__ === Object.prototype ){
return
}
//输出顺序和上面一致
obj.__proto__.some();
outSome(obj.__proto__)
}
outSome(p1)
对象名.__proto__ 和 Object.getPrototypeOf(对象名)
//ture 执行的是同个原型对象
console.log(p1.__proto__ === Object.getPrototypeOf(p1));
向上查找机制
//p1对象没有some()方法找原型对象
//Man-some
p1.some()
//p1原型对象的some()方法
//Man-Same
p1.__proto__.some()
//true
//证明p1.some()实际上调用的是p1.__proto__.some()
console.log(p1.some === p1.__proto__.some);
//Person-Same
p1.__proto__.__proto__.some()
//false
console.log(p1.some === p1.__proto__.__proto__.some)
递归调用
//通过递归的方式输出
const outSome = (obj) => {
//判断对象是非空
if(!obj){
return
}
/**
* 判断对象的原型是不是指向Object.prototype
* 因为Object.prototype里面没有定义some()方法
*/
if(obj.__proto__ === Object.prototype ){
return
}
//输出顺序和上面一致
obj.__proto__.some();
outSome(obj.__proto__)
}
outSome(p1)