JavaScript原型链

目录

  1. 创建对象有几种方法
  2. 原型、构造函数、实例、原型链
  3. instanceof的原理
  4. new运算符

创建对象的方法

  在了解原型链之前,首先先了解一下创建对象的几种方式,介绍以下三种。

代码:

<script type="text/javascript">
// 第一种方式:字面量
var o1 = {name: 'o1'}
var o2 = new Object({name: 'o2'})
// 第二种方式:构造函数
var M = function (name) { this.name = name; }
var o3 = new M('o3')
// 第三种方式:Object.create
var p = {name: 'p'}
var o4 = Object.create(p)   console.log(o1)    
  console.log(o2)
  console.log(o3)
  console.log(o4)
</script>

打印结果:

对象是创建出来了,但你可能对结果很诧异,为什么不同呢?别急,慢慢来。

原型及原型链

先来一张容易让人懵逼的图

什么是原型对象?实例?构造函数?

概念就不多说了,看代码吧

var M = function (name) { this.name = name; }
var o3 = new M('o3')
  • 实例就是对象,在本例中o3就是实例,M就是构造函数。
  • 实例通过new一个构造函数生成的。
  • 从上图中可以知道,实例的__protpo__指向的是原型对象。
  • 实例的构造函数的prototype也是指向的原型对象。
  • 原型对象的construor指向的是构造函数。

再来通过下面这个图来理解一下

那什么是原型链呢?

简单理解就是原型组成的链,对象的__proto__它的是原型,而原型也是一个对象,也有__proto__属性,原型的__proto__又是原型的原型,就这样可以一直通过__proto__想上找,这就是原型链,当向上找找到Object的原型的时候,这条原型链就算到头了。

原型对象和实例之间有什么作用呢?

通过一个构造函数创建出来的多个实例,如果都要添加一个方法,给每个实例去添加并不是一个明智的选择。这时就该用上原型了。

在实例的原型上添加一个方法,这个原型的所有实例便都有了这个方法。

接着上面的例子继续演示:

var M = function (name) { this.name = name; }
var o3 = new M('o3')
var o5 = new M()
o3.__proto__.say=furnction(){
console.log('hello world')
} o3.say()
o5.say()

打印结果

按照JS引擎的分析方式,在访问一个实例的属性的时候,现在实例本身中找,如果没找到就去它的原型中找,还没找到就再往上找,直到找到。这就是原型链。

补充:

只有函数有prototype,对象是没有的。

但是函数也是有__proto__的,因为函数也是对象。函数的__proto__指向的是Function.prototype。

也就是说普通函数是Function这个构造函数的一个实例。

instanceof原理

instanceof是判断实例对象的__proto__和生成该实例的构造函数的prototype是不是引用的同一个地址。

是返回true,否返回false。

注意:实例的instanceof在比较的时候,与原型链上想上找的的构造函数相比都是true。

继续上面的代码

那怎么判断实例是由哪个构造函数生成的呢?这时候就要用到constructor了。

实例的原型的构造函数, obj.__proto__.constructor

new运算符

new运算符的原理

  • 一个新对象被创建。它继承自foo.prototype。
  • 构造函数返回一个对象。在执行的时候,相应的传参会被传入,同时上下文(this)会被指定为这个新的实例。
  • new foo等同于new foo(), 只能用在不传递任何参数的情况
  • 如果构造函数反悔了一个对象,那个这个对象会取代整个new出来的结果。如果构造函数没有返回对象,那个new出来的结果为步骤1创建的对象。

下面根据new的工作原理通过代码手动实现一下new运算符

var new2 = function (func) {
var o = Object.create(func.prototype);    //创建对象
var k = func.call(o);             //改变this指向,把结果付给k
if (typeof k === 'object') {         //判断k的类型是不是对象
return k;                  //是,返回k
} else {
return o;                  //不是返回返回构造函数的执行结果
}
}

验证

经过上图一系列折腾,不难看出,我们手动编写的new2和new运算符的作用是一样的。

通过这个例子,你是不是已经熟知了new的工作原理了呢

资料--JavaScript原型链的更多相关文章

  1. Javascript 原型链资料收集

    Javascript 原型链资料收集 先收集,后理解. 理解JavaScript的原型链和继承 https://blog.oyanglul.us/javascript/understand-proto ...

  2. javascript原型链中 this 的指向

    为了弄清楚Javascript原型链中的this指向问题,我写了个代码来测试: var d = { d: 40 }; var a = { x: 10, calculate: function (z) ...

  3. JavaScript学习总结(十七)——Javascript原型链的原理

    一.JavaScript原型链 ECMAScript中描述了原型链的概念,并将原型链作为实现继承的主要方法.其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法.在JavaScript中, ...

  4. 明白JavaScript原型链和JavaScrip继承

    原型链是JavaScript的基础性内容之一.其本质是JavaScript内部的设计逻辑. 首先看一组代码: <script type="text/javascript"&g ...

  5. JavaScript原型链:prototype与__proto__

    title: 'JavaScript原型链:prototype与__proto__' toc: false date: 2018-09-04 11:16:54 主要看了这一篇,讲解的很清晰,最主要的一 ...

  6. JavaScript原型链及其污染

    JavaScript原型链及其污染 一.什么是原型链? 1.JavaScript中,我们如果要define一个类,需要以define"构造函数"的方式来define: functi ...

  7. 图解Javascript原型链

    本文尝试阐述Js中原型(prototype).原型链(prototype chain)等概念及其作用机制.上一篇文章(图解Javascript上下文与作用域)介绍了Js中变量作用域的相关概念,实际上关 ...

  8. 简单粗暴地理解 JavaScript 原型链 (一个充满歪门邪理的理解方法,有助于新手哦!)

    原型链理解起来有点绕了,网上资料也是很多,每次晚上睡不着的时候总喜欢在网上找点原型链和闭包的文章看,效果极好. 不要纠结于那一堆术语了,那除了让你脑筋拧成麻花,真的不能帮你什么.简单粗暴点看原型链吧, ...

  9. 画一画javascript原型链

    在javascript中,几种数据类型String,Number,Boolean,Object,Function都是函数,可称之为函数对象. 可以说拥有prototype属性的都是函数. 所有对象都拥 ...

随机推荐

  1. MySQL的基础(优化)1

    1,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小 2,在可能的情况下,应该尽量把字段设置为NOT NULL,这样在将来执行查询的时候,数据库不用去比较NULL值 3,对于某 ...

  2. Linux 使用第三方邮箱发邮件的设置

    mail命令在Ubuntu下是需要安装的,使用下条命令进行安装: sudo apt-get install heirloom-mailx 在CentOS 下安装则是: yum install mail ...

  3. 【js基础修炼之路】- 手把手教你实现bind

    手写bind前我们先回顾一下bind有哪些特性,以便更好的理解bind和实现bind. bind的特性 var obj = { a: 100, say(one, two) { console.log( ...

  4. 安卓手机下载YouTube视频的3种方法

    作为全球最大的在线视频网站,YouTube上面的内容可真是应有尽有啊,从教学视频到个人手工艺品制作流程,从各种搞笑视频到电视连续集等等,包罗万象.如果你想下载YouTube视频到电脑上面的话,网上有很 ...

  5. SQL的注入式攻击方式和避免方法

    SQL 注入是一种攻击方式,在这种攻击方式中,恶意代码被插入到字符串中,然后将该字符串传递到 SQL Server 的实例以进行分析和执行.任何构成 SQL 语句的过程都应进行注入漏洞检查,因为 SQ ...

  6. 后缀数组入门(二)——Height数组与LCP

    前言 看这篇博客前,先去了解一下后缀数组的基本操作吧:后缀数组入门(一)--后缀排序. 这篇博客的内容,主要建立于后缀排序的基础之上,进一步研究一个\(Height\)数组以及如何求\(LCP\). ...

  7. 4. NBU文件备份与恢复,图形界面&字符界面操作

    一. 图形界面文件备份与恢复 1.1  文件备份 待补充 1.2 Windows文件恢复 (1) 打开恢复客户端 (2) 检查设置 (3) 查询可恢复信息 (4) 选取恢复时间点和文件 (5) 选择恢 ...

  8. [Pytorch] pytorch笔记 <三>

    pytorch笔记 optimizer.zero_grad() 将梯度变为0,用于每个batch最开始,因为梯度在不同batch之间不是累加的,所以必须在每个batch开始的时候初始化累计梯度,重置为 ...

  9. 某寺庙,有小和尚、老和尚若干。有一水缸,由小和尚用水桶从井中提水入缸,老和尚用水桶从缸里取水饮用。水缸可容10桶水,水取自同一井中。水井径窄,每次只能容一个水桶取水。水桶总数为3个。每次入、取缸水仅为1桶,且不可以同时进行。试用P、V操作给出小和尚、老和尚动作的算法描述。

    寺庙和尚打水 设信号量mutex_gang, mutex_jing, gang_empty, gang_full, count分别表示使用缸互斥, 使用井互斥, 缸空, 缸满, 水桶总个数 semap ...

  10. 7-4 python 接口开发(提供mock服务)

    1.登录接口开发(数据存在数据库中)  接口开发做mock(模拟功能) tools.py import pymysql def my_db(sql): conn = pymysql.connect(h ...