<center>原型链</center>

原型链

JS的原型与原型链,相较于普通语法,它更难以理解一些,在开发上也较不常见。但这并不意为这它不重要,相反,它很重要。
在这里插入图片描述
在这里插入图片描述

prototype 与 proto

prototype 与 proto(双下划线) 很容易混淆,它们之间的指向有些复杂,避免难以理解,我们尝试用最简单的图示将其说明清楚他们的区别
  我们知道,原型本质也是一个对象,其他对象可以通过它实现属性继承。看看一下图
在这里插入图片描述

在大多数情况下,__proto__可以理解为 构造器的原型,即:proto === constructor.prototype (Object.create 方式除外)这里只是初步理解,不太准确,请继续往下看
  用代码解释,代码很简单,但是希望看官自己敲一敲看看控制台表现,实践了理解才更加深刻。如下:

var a = {};
console.log(a.prototype);   // undefined
console.log(a.__proto__);   // Object ()

var b = function() {
}
console.log(b.prototype);  // b {}
console.log(b.__proto__);   // function() {}

在这里插入图片描述
当然,如果定义 var a = “”; 那么将输出
在这里插入图片描述
_proto_属性指向谁
  __proto__的指向取决于对象创建时的实现方式。以下图表列出了三种常见方式创建对象后,__proto__分别指向谁

1. 字面量方式

    var a = {};
    console.log(a.__proto__);  // Object {}
    console.log(a.__proto__ === a.constructor.prototype);   // true

在这里插在这里插入图片描述入图片描述

2. 构造器方式

var A = function() {};
var a = new A();
console.log(a.__proto__); // A {}
console.log(a.__proto__ === a.constructor.prototype);  // true

在这里插入图片描述
即 由构造函数A 构造出的实例函数a, 那么a的原型就是构造函数A

  1. Object.create 方式

var a1 = {};
var a2 = Object.create(a1);
console.log(a2__proto__); // Object {a: 1}
console.log(a.proto === a.constructor.prototype); // false

var a1 = {};
var a2 = Object.create(a1);
console.log(a2__proto__);  // Object {a: 1}
console.log(a.__proto__ === a.constructor.prototype);  // false

在这里插入图片描述

原型链

由于__proto__是任何对象都有的属性,而js里万物皆对线个,所以会形成一条__proto__连起来的链条, 递归访问__proto__必须最终到头,且值为null.
  当js引擎查找对象的属性时,县查找对象本身是否存在该属性,如果不存在,会在原型链上查找,但不会查找自身的prototype

在这里插入图片描述

var A = function() {};
var a = new A();
console.log(a.__proto__);  // A {};  实例对象a的原型是构造器A的原型对象
console.log(a.__proto__.__proto__);  // Object {} 构造器A的原型是function Object的原型对象
console.log(a.__proto__.__proto__.__proto__);  // null

实例分析

在理解原型与原型链的概念区别信息之后,我们来看看如下案例(注意大小写规范,意义不一致)

function Person(name) {
   this.name = name;
}

function Mother() { }
Mother.prototype = {
  age: 18,
  home: ['Beijing']
}

Person.prototype = new Mother();

var p1 = new Person('Jack');
var p2 = new Person('Mark');
console.log(p1);    // 见下图
console.log(p2);
console.log(p1.age);  // 18

p1对象的数据结构

在这个例子中, Person就是一个构造函数,我们使用new创建了一个实例对象person。并且,将这个实例对象的原型指向Mother。
  那么,在执行console.log(p1)时,我们知道,它会先去找p1的实例属性,在实例属性中找不到后再去找原型属性,最终打印出18
  p2的打印结果,与p1类似,除了name属性外

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值