javascript 原型与原型链

原型与原型链

一、prototype 和 __proto__的区别

  1. 我们每创建一个函数,解析器都会向里添加一个prototype属性,该属性指向函数的原型对象。
  2. __proto__是每个对象都有的隐含属性。
    在这里插入图片描述
var obj = {};
console.log("obj.prototype:",obj.prototype);  
console.log("obj.__proto__:", obj.__proto__); 

var fun= function () { }
console.log("fun.prototype:", fun.prototype);  
console.log("fun.__proto__:", fun.__proto__);  

在这里插入图片描述

每个对象都有 __proto__ 属性,但只有函数对象才有 prototype 属性

二、验证__proto__ 指向

一个对象的__proto__属性指向创建该对象的构造函数的原型,这也保证了实例能够访问,在构造函数原型中定义的属性和方法。

__proto__是每个对象有的属性,那我们就从对象下手,下面列举几种常见创建对象的方式,来看看他们的__proto__指向。

  1. 字面量方式
let obj = {};
console.log("obj.__proto__:", obj.__proto__);
console.log( obj.__proto__ === obj.constructor.prototype);

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

  1. 构造器方式
let Fun = function() {};
let obj = new Fun();
console.log("obj.__proto__:", obj.__proto__);
console.log(obj.__proto__ === obj.constructor.prototype);

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

  1. Object.create()方式
var obj1 = { a: 1 }
var obj2 = Object.create(obj1);
console.log(obj2.__proto__); 
console.log(obj2.__proto__ === obj1.constructor.prototype);

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

三、原型

JavaScript中,每当我们创建(或声明)一个函数,浏览器都会向里面添加一个 prototype 属性,该属性的值对应着一个对象,指向了当前函数的引用地址。这个对象就是我们所谓的原型对象,简称函数的原型。原型对象有一个默认属性 constructor ,该属性指向了这个函数 (即:constructor 属性的值是这个函数 )。

//声明一个函数Person 
function Person() {}

声明一个 Person 函数后发生的事情:
在这里插入图片描述

Person 就是构造函数,Person.prototype 就是原型

如果Person 函数作为普通函数调用,那么 prototype 作用不大,可以说是没有任何作用,但以构造函数的形式调用时,它所创建出的对象中都会有一个隐含的__proto__属性,该属性指向创建它的构造函数的原型对象。

function Person () {}	
var p1 = new Person();
console.log("p1.__proto__:", p1.__proto__);

在这里插入图片描述
上面代码示意图:
在这里插入图片描述简易图:
在这里插入图片描述

构造函数 Person ,也可以称之为
通过构造函数 Person 创建的对象p1,可称为实例对象

原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象。

function Person() {}
Person.prototype.x = 10;
Person.prototype.y = 20;
var p1 = new Person();
p1.z = 30;
var p2 = new Person();
p2.z = 40;
console.log("p1.x:", p1.x, "p1.y:", p1.y, "p1.z:", p1.z);
console.log("p2.x:", p2.x, "p2.y:", p2.y, "p2.z:", p2.z);

输出结果:
在这里插入图片描述
上面代码的示意图:
在这里插入图片描述

四、原型链

当我们访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的prototype__proto__中查找,最后会到达顶层的Object prototype,它的__proto__指向null,均无结果最后则返回undefined,结束。这样一层一层向上查找就会形成一个链式结构,我们称为原型链。

function Fun(){};
var f = new Fun();
console.log(f.__proto__); 
console.log(f.__proto__.__proto__); 
console.log(f.__proto__.__proto__.__proto__);

执行结果:
在这里插入图片描述
画图理解:
在这里插入图片描述
简易版图解:

在这里插入图片描述

五、玄学

函数(function)概念:函数简单的说就是可以重复执行的代码块。( 只定义一次,但可能被执行(或调用)任意次的一段 JavaScript 代码块)
构造函数(constructor):一种专门创建对象时使用的特殊函数。

  1. Object 的生成
    在这里插入图片描述
  2. function Object 同时也是一个对象,它的原型是Function.prototype,该原型用来描述所有的函数。
console.log(Object.__proto__ === Function.prototype);
console.log(Function.__proto__ === Function.prototype);
console.log(Function.prototype.__proto__ === Object.prototype);
console.log(Object.prototype.__proto__ === null);

运行结果:
在这里插入图片描述看图理解:

在这里插入图片描述总结起来就是:鸡生蛋蛋生鸡

在这里插入图片描述

六、经典图例

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值