一、原型

JavaScript 常被描述为一种基于原型的语言——每个对象拥有一个原型对象

当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾

准确地说,这些属性和方法定义在Object的构造器函数(constructor functions)之上的prototype属性上,而非实例对象本身

  1、所有的函数天生都有一个对象(显示原型对象)‘prototype’,构造函数也有显示原型‘prototype’,指向原型

  2、所有的对象天生都有一个对象(隐式原型对象)‘__proto__’,实例对象也有隐式原型’__proto__‘,指向原型

  3、在原型当中有一个属性(constructor)指向构造函数

  

下面举个例子:

函数可以有属性。 每个函数都有一个特殊的属性叫作原型prototype

function doSomething(){}
console.log( doSomething.prototype );

控制台输出

{
constructor: ƒ doSomething(),
__proto__: {
constructor: ƒ Object(),
hasOwnProperty: ƒ hasOwnProperty(),
isPrototypeOf: ƒ isPrototypeOf(),
propertyIsEnumerable: ƒ propertyIsEnumerable(),
toLocaleString: ƒ toLocaleString(),
toString: ƒ toString(),
valueOf: ƒ valueOf()
}
}

上面这个对象,就是大家常说的原型对象

可以看到,原型对象有一个自有属性constructor,这个属性指向该函数,如下图关系展示

二、原型链

原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。这种关系常被称为原型链 (prototype chain),它解释了为何一个对象会拥有定义在其他对象中的属性和方法

在对象实例和它的构造器之间建立一个链接(它是__proto__属性,是从构造函数的prototype属性派生的),之后通过上溯原型链,在构造器中找到这些属性和方法

下面举个例子:

function Person(name) {
this.name = name;
this.age = 18;
this.sayName = function() {
console.log(this.name);
}
}
// 第二步 创建实例
var person = new Person('person')

根据代码,我们可以得到下图

下面分析一下:

  • 构造函数Person存在原型对象Person.prototype

  • 构造函数生成实例对象personperson__proto__指向构造函数Person原型对象

  • Person.prototype.__proto__ 指向内置对象,因为 Person.prototype 是个对象,默认是由 Object函数作为类创建的,而 Object.prototype 为内置对象

  • Person.__proto__ 指向内置匿名函数 anonymous,因为 Person 是个函数对象,默认由 Function 作为类创建

  • Function.prototype 和 Function.__proto__同时指向内置匿名函数 anonymous,这样原型链的终点就是 null

三、总结

下面首先要看几个概念:

__proto__作为不同对象之间的桥梁,用来指向创建它的构造函数的原型对象的

每个对象的__proto__都是指向它的构造函数的原型对象prototype

person1.__proto__ === Person.prototype

构造函数是一个函数对象,是通过 Function构造器产生的

Person.__proto__ === Function.prototype

原型对象本身是一个普通对象,而普通对象的构造函数都是Object

Person.prototype.__proto__ === Object.prototype

刚刚上面说了,所有的构造器都是函数对象,函数对象都是 Function构造产生的

Object.__proto__ === Function.prototype

Object的原型对象也有__proto__属性指向nullnull是原型链的顶端

Object.prototype.__proto__ === null

下面作出总结:

  • 一切对象都是继承自Object对象,Object 对象直接继承根源对象null

  • 一切的函数对象(包括 Object 对象),都是继承自 Function 对象

  • Object 对象直接继承自 Function 对象

  • Function对象的__proto__会指向自己的原型对象,最终还是继承自Object对象

JavaScript原型和原型链?有什么特点?的更多相关文章

  1. JavaScript继承与原型链

    对于那些熟悉基于类的面向对象语言(Java 或者 C++)的开发者来说,JavaScript 的语法是比较怪异的,这是由于 JavaScript 是一门动态语言,而且它没有类的概念( ES6 新增了c ...

  2. 【javascript基础】4、原型与原型链

    前言 荒废了好几天,在宿舍闷了几天了,一直想着回家放松,什么也没搞,论文就让老师催吧.不过,闲的没事干的感觉真是不好,还是看看书,写写博客吧,今天和大家说说函数的原型. 原型是什么 第一次看到这个的时 ...

  3. 【JavaScript】深入理解JavaScript之强大的原型和原型链

    由于JavaScript是唯一一个被广泛使用的基于原型继承的语言,所以理解两种继承模式的差异是需要一定时间的,今天我们就来了解一下原型和原型链. AD: hasOwnProperty函数: hasOw ...

  4. Javascript 原型和原型链

    先来了解一下Javascript中的原型:”原型也是一个对象,原型可以用来实现继承...“ 对于 原型,构造函数,以及实例之间的关系:“每个(构造)函数都有一个原型属性,原型对象都包含一个指向构造函数 ...

  5. javascript 原型 和 原型链

    最近几天,好些新同事来问原型,原型链啥的.本身作为菜鸟的我好像也没有好好整理过这个,这里写写自己的理解. 原型 大家都知道,JavaScript 不包含传统的类继承模型,而是使用 prototype ...

  6. JavaScript深入之从原型到原型链(本文转载)

    JavaScript深入之从原型到原型链(本文转载) https://github.com/mqyqingfeng/Blog.原文地址 构造函数创建对象 我们先使用构造函数创建一个对象: functi ...

  7. javascript 之原型、原型链-14

    原型 原型是一个对象,每个函数对象(在javascript 之对象中说过函数也是对象 )都有一个属性(prototype)指向这个对象--原型对象,这个对象的作用是让所有对象实例共享原型对象中的属性. ...

  8. JavaScript原型与原型链

    一.数据类型 JavaScript的数据类型可以分为基本数据类型和引用数据类型. 基本数据类型(6种) String Number Boolean null undefined Symbol(ES6) ...

  9. JavaScript prototype原型和原型链详解

    用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,可以为其添加函数供实例访问,其它的就不清楚了, ...

  10. 对Javascript 类、原型链、继承的理解

    一.序言   和其他面向对象的语言(如Java)不同,Javascript语言对类的实现和继承的实现没有标准的定义,而是将这些交给了程序员,让程序员更加灵活地(当然刚开始也更加头疼)去定义类,实现继承 ...

随机推荐

  1. PHY驱动调试之 ---PHY设备驱动(三)

    1. 前言 内核版本:linux 4.9.225,以freescale为例.(部分内容待修改和补充,不一定准确) 2. 概述 上一篇文章讲了控制器的驱动使用的是platform总线的连接方式,本节要讲 ...

  2. springboot +mybatis (@autowried 注入mapper :爆红)

    问题描述:Could not autowire. No beans of XXXXmapper' type found 问题相关页面: 解决方式一:@mapper  接口计入@Repository 解 ...

  3. vscode配置remote ssh

    前言 简单用vscode配置 remote ssh可以实现,通过ssh 在线使用vscode编辑文件,很方便,也遇到一些坑. 安装插件 设置界面 右键最左边tab栏: 勾选 远程资源管理器 添加远程服 ...

  4. 关于linux mint更改资源管理器的快捷键

    前言 首先要知道 linux mint 的默认资源管理器是 nemo 我很不习惯 ctrl+d 在nemo里面是 收藏到侧边栏 我习惯 ctrl+d 在windows上是删除文件 所以下面我就修改这个 ...

  5. day01-家具网购项目说明

    家具网购项目说明 1.项目前置技术 Java基础 正则表达式 Mysql JDBC 数据库连接池技术 满汉楼项目(包括框架图) JavaWeb 2.相关说明 这里先使用原生的servlet/过滤器,后 ...

  6. 历时9个月重构iNeuOS工业互联网操作系统,打造工业领域的“Office”

    目       录 1.      概述... 1 2.      整体介绍... 2 3.      主要功能简介... 5 1.   概述 历时9个月的时间,对iNeuOS工业互联网操作系统进行全 ...

  7. [编程基础] Python日志记录库logging总结

    Python日志记录教程展示了如何使用日志记录模块在Python中进行日志记录. 文章目录 1 介绍 1.1 背景 1.2 Python日志记录模块 1.3 根记录器 2 Python logging ...

  8. .Net 7 内存模型函数描述结构MethoDesc

    楔子 讲一些CLR里面的内存模型.本篇MethodDesc,意为函数的描述之意,看下一个函数在CLR里面是如何被描述的. MethodDesc结构 这个结构体在CLR里面高达1600多行,这里仅截取一 ...

  9. [WPF]鼠标移动到Button颜色改变效果设置

    代码 <Style x:Key="Button_Menu" TargetType="{x:Type Button}"> <Setter Pro ...

  10. rvm安装ruby

    macOS11.1 打开终端 使用下面命令查看ruby版本 rvm list known 然后安装 rvm install 2.0.0 查看ruby版本 ruby -v   系统默认使用ruby版本 ...