JavaScript 原型和原型链

在阅读本文章之前,已经默认你了解了基础的 JavaScript 语法知识,基础的 ES6 语法知识 。

本篇文章旨在为 JavaScript继承 打下基础

原型

  1. JavaScript 里任何一个函数都有一个 prototype 属性,这个属性称之为原型
function Person() {
this.name = "name";
}
console.log(Person.prototype)

Person.prototype 实际上是一个包含 constructor 属性的对象

constructor 实际上就是构造函数本身

// Person.prototype
{
constructor: Person
}
  1. Person.prototype 指向的对象很特殊(原型链学完就明白为什么特殊了),可以被实例所共享,可以作为实例的属性直接调用
const obj1 = new Person();
const obj2 = new Person();
console.log(obj1.constructor === obj2.constructor) // true
console.log(obj1.constructor === Person) // true

这意味着,我们可以在 Person.prototype 上加一些共享属性或者方法,然后直接在实例中共享

Person.prototype.eat = function() {
console.log("eat");
} // 现在
obj1.eat(); // "eat";
obj2.eat(); // "eat";

上面,我们简要的说明了原型,以及原型的作用,下面我们探索原型链

原型链

我们先看一个小例子

function Person() {
this.name = "name";
} const p = new Person();
p.toString(); // [object Object]

我们并没有在 Person.prototype 上定义 toString 这个方法,按理来说当我们调用的时候应该报错 ,然而浏览器却 "不厚道" 的输出了 [object Object]

要解释这个原因,还有 "很长的路" 要走。

  1. 首先任何实例化出来的对象都拥有 __proto__ 属性,这个属性指向构造函数的 prototype
console.log(p.__proto__ === Person.prototype) // true

之前我们写过这样的代码

Person.prototype.eat = function() {
console.log("eat");
} obj1.eat(); // "eat";
obj2.eat(); // "eat";

我们惊讶的发现, obj1 上也可以拥有 eat 方法了。

  1. 如果一个对象上没有这个属性,他就会去他的 __proto__ 属性对应的对象上去找,如果还没有就继续这个对象的 __proto__上去找

那么 Person.prototype 是否有 __proto__

console.log(Person.prototype.__proto__);

在这里输出的结果中有 constuctor: Object

之前提到 constuctor 其实就是构造函数本身,因此

console.log(Person.prototype.__proto__ === Object.prototype); // true

我们在 Object.prototype 中发现了这个方法,并进行调用

console.log(Object.prototype.hasOwnProperty("toString")) // true
Object.prototype.toString.call(p); // [object Object]

至此原型链基本是说完了,有兴趣的可以探究一下

  1. Object.prototype 是否有 __proto__ ?
  2. 构造函数是否也是被实例化出来的?
  3. 数组的原型链是什么样的

对于第三题,有兴趣的可以自己画一下图

console.log(Array.prototype.__proto__ === Object.prototype) // true

一篇文章图文并茂地带你轻松学完 JavaScript 原型和原型链的更多相关文章

  1. 一篇文章图文并茂地带你轻松学完 JavaScript 设计模式(一)

    JavaScript 设计模式(一) 本文需要读者至少拥有基础的 ES6 知识,包括 Proxy, Reflect 以及 Generator 函数等. 至于这次为什么分了两篇文章,有损传统以及标题的正 ...

  2. 一篇文章图文并茂地带你轻松学完 JavaScript 设计模式(二)

    JavaScript 设计模式(二) 本篇文章是 JavaScript 设计模式的第二篇文章,如果没有看过我上篇文章的读者,可以先看完 上篇文章 后再看这篇文章,当然两篇文章并没有过多的依赖性. 5. ...

  3. 一篇文章图文并茂地带你轻松学完 JavaScript 继承

    JavaScript 继承 在阅读本文章之前,已经默认你了解了基础的 JavaScript 语法知识,基础的 ES6 语法知识 . 继承种类 简单的继承种类可以分为 构造函数继承 原型链继承 clas ...

  4. 一篇文章图文并茂地带你轻松学完 JavaScript 事件循环机制(event loop)

    JavaScript 事件循环机制 (event loop) 本篇文章已经默认你有了基础的 ES6 和 javascript语法 知识. 本篇文章比较细致,如果已经对同步异步,单线程等概念比较熟悉的读 ...

  5. 一篇文章图文并茂地带你轻松学完 JavaScript 闭包

    JavaScript 闭包 为了更好地理解 JavaScript 闭包,笔者将先从 JavaScript 执行上下文以及 JavaScript 作用域开始写起,如果读者对这方面已经了解了,可以直接跳过 ...

  6. 一篇文章图文并茂地带你轻松实践 HTML5 history api

    HTML5 history api 前言 由于笔者在网络上没有找到比较好的关于 history api 的实践案例,有的案例过于杂乱,没有重点,有些案例只是告诉读者 api 是什么,却没告诉怎么用,本 ...

  7. 一篇文章图文并茂地带你轻松学会 HTML5 storage

    html5 storage api localStorage 和 sessionStorage 是 html5 新增的用来存储数据的对象,他们让我们可以以键值对的形式存储信息. 为什么要有 stora ...

  8. 一篇文章让你快速入门 学懂Shell脚本

    Shell脚本,就是利用Shell的命令解释的功能,对一个纯文本的文件进行解析,然后执行这些功能,也可以说Shell脚本就是一系列命令的集合. Shell可以直接使用在win/Unix/Linux上面 ...

  9. 学完JavaScript基础有感

    紧接上一篇回来了,这几天一直学js,会不自觉的和其他的编程语言联系在一起,在没有学jQuery之前,结合我所学的c,java,数据结构,数据库以及部分html感觉到JavaScript里面又很多相似的 ...

随机推荐

  1. windows端口占用

    原文链接http://zhhll.icu/2020/04/08/windows/windows%E4%B9%8B%E7%AB%AF%E5%8F%A3%E5%8D%A0%E7%94%A8/ 1.查看当前 ...

  2. Spring Boot 2.x基础教程:使用Flyway管理数据库版本

    之前已经介绍了很多在Spring Boot中使用MySQL的案例,包含了Spring Boot最原始的JdbcTemplate.Spring Data JPA以及我们国内最常用的MyBatis.同时, ...

  3. Windows 2008 Server R2双网卡负载均衡

    源文档 <http://blog.sina.com.cn/s/blog_6025f5690101apwd.html>

  4. 一道有趣的golang排错题

    很久没写博客了,不得不说go语言爱好者周刊是个宝贝,本来想随便看看打发时间的,没想到一下子给了我久违的灵感. go语言爱好者周刊78期出了一道非常有意思的题目. 我们来看看题目.先给出如下的代码: p ...

  5. Kubernetes K8S之kube-prometheus概述与部署

    Kubernetes K8S之kube-prometheus概述与部署 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7. ...

  6. VBScript调用winscp,实现sftp操作

    最新有一个需求,需要在ssis中调用sftp下载文件,由于服务器上只有framework2.0,并且需要用sqlserver代理调用作业,限制了很多. 首先用的是脚本任务,进程调用winscp.com ...

  7. Python Debug工具

    最近在github上冒出了一个python的debug神器PySnooper,号称在debug时可以消灭print.那么该工具有哪些优点呢,如何使用该工具呢.本文就介绍该工具的优缺点和使用方式. 前言 ...

  8. Py变量,递归,作用域,匿名函数

    局部变量与全局变量 全局变量:全局生效的变量,在顶头的,无缩进的定义的变量. 局部变量:函数内生效的变量,在函数内定义的变量. name='1fh' def changename(): name='s ...

  9. NFS存储迁移至GlusterFS

    NFS存储迁移至GlusterFS 前提条件 为防止脑裂,建议使用最低3台节点制作3复制集的存储卷: 在进行存储迁移前,GluseterFS存储节点需先成为k8s集群中的node节点: 存储切换时请勿 ...

  10. 全栈性能测试修炼宝典-JMeter实战笔记(一)

    了解性能测试 性能测试不仅能够定位.分析问题,还要把握系统性能变化趋势:性能测试工程师能够帮助解决性能问题,搞定测试过程中的各种不合理配置,给出专业的优化建议. 第一章 性能方向职业发展 软件测试职业 ...