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. docker基本入门知识-小白向

    基本概念 Docker是一个开源项目,前身是dotCloud公司的内部项目,但苦于无法扩大使用和推广,后期开源后吸引大量的开发人员的参与,以至于公司直接改名为Docker Inc. Docker项目的 ...

  2. js--获取滚动条位置,并实现页面滑动到锚点位置

    前言 这篇来记录下最近工作中遇到的一个问题,在app原生和前端h5混合开发的过程中,其中一个页面是选择城市列表的页面,类似于美团饿了么城市选择,银行app中银行列表选择,通讯录中快速定位到联系人选择的 ...

  3. 一键配置网卡IP(win10)脚本

    前两天有个小伙伴问我,如何快速配置IP,在公司在家里在宿舍,快速配置IP,然后我特别为这个小伙伴写了一个脚本. @echo off mode con: cols=60 lines=25 title 网 ...

  4. vue 深度作用选择器

    使用 scoped 后,父组件的样式将不会渗透到子组件中 如果想在使用scoped,不污染全局的情况下,依然可以修改子组件样式,可以使用深度作用选择器 .tree{ width: 100%; floa ...

  5. 【Spring】Spring JdbcTemplate

    Spring JdbcTemplate 文章源码 JdbcTemplate 概述 它是 Spring 框架中提供的一个对象,是对原始 Jdbc API 对象的简单封装.Spring 框架提供了很多的操 ...

  6. LeetCode394 字符串解码

    给定一个经过编码的字符串,返回它解码后的字符串. 编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次.注意 k 保证为正整数. 你可 ...

  7. ssh连接不上vmware虚拟机centos7.5

    在vmware中安装centos7.5后,手动设置IP地址192.168.1.5,发现主机ping不通虚拟机的IP,以下是我的解决办法 1.vmware设置选择仅主机模式 2.在主机查看vmnet1( ...

  8. 克隆slave

    在日常生活中,我们做的比较多的操作就是在线添加从库,比如线上有一主一丛两个数据库,由于业务的需要一台从库的读取量无法满足现在的需求,这样就需要我们在线添加从库,出于安全考虑,我们通常需要在从库上进行在 ...

  9. PHP MySQLi extension is not loaded

    PHP MySQLi extension is not loaded 如何解决呢?  yum -y install mysqli.so  huozhe yum -y install php-mysql

  10. 【Oracle】更改oracle中的用户名称

    修改oracle中的用户名,要需要修改oracle基表中的相关内容, 1.查看user#, select user#,name from user$ s where s.name='用户修改前的'; ...