资料--JavaScript原型链
JavaScript原型链
目录
- 创建对象有几种方法
- 原型、构造函数、实例、原型链
- instanceof的原理
- 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原型链的更多相关文章
- Javascript 原型链资料收集
Javascript 原型链资料收集 先收集,后理解. 理解JavaScript的原型链和继承 https://blog.oyanglul.us/javascript/understand-proto ...
- javascript原型链中 this 的指向
为了弄清楚Javascript原型链中的this指向问题,我写了个代码来测试: var d = { d: 40 }; var a = { x: 10, calculate: function (z) ...
- JavaScript学习总结(十七)——Javascript原型链的原理
一.JavaScript原型链 ECMAScript中描述了原型链的概念,并将原型链作为实现继承的主要方法.其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法.在JavaScript中, ...
- 明白JavaScript原型链和JavaScrip继承
原型链是JavaScript的基础性内容之一.其本质是JavaScript内部的设计逻辑. 首先看一组代码: <script type="text/javascript"&g ...
- JavaScript原型链:prototype与__proto__
title: 'JavaScript原型链:prototype与__proto__' toc: false date: 2018-09-04 11:16:54 主要看了这一篇,讲解的很清晰,最主要的一 ...
- JavaScript原型链及其污染
JavaScript原型链及其污染 一.什么是原型链? 1.JavaScript中,我们如果要define一个类,需要以define"构造函数"的方式来define: functi ...
- 图解Javascript原型链
本文尝试阐述Js中原型(prototype).原型链(prototype chain)等概念及其作用机制.上一篇文章(图解Javascript上下文与作用域)介绍了Js中变量作用域的相关概念,实际上关 ...
- 简单粗暴地理解 JavaScript 原型链 (一个充满歪门邪理的理解方法,有助于新手哦!)
原型链理解起来有点绕了,网上资料也是很多,每次晚上睡不着的时候总喜欢在网上找点原型链和闭包的文章看,效果极好. 不要纠结于那一堆术语了,那除了让你脑筋拧成麻花,真的不能帮你什么.简单粗暴点看原型链吧, ...
- 画一画javascript原型链
在javascript中,几种数据类型String,Number,Boolean,Object,Function都是函数,可称之为函数对象. 可以说拥有prototype属性的都是函数. 所有对象都拥 ...
随机推荐
- SpringBoot支持Xml数据格式显示
第一步:pom文件添加依赖 <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> < ...
- hive自定义UDTF函数叉分函数
hive自定义UDTF函数叉分函数 1.介绍 从聚合体日志中需要拆解出来各子日志数据,然后单独插入到各日志子表中.通过表生成函数完成这一过程. 2.定义ForkLogUDTF 2.1 HiveUtil ...
- 笨办法学Python(二十三)
习题 23: 读代码 上一周你应该已经牢记了你的符号列表.现在你需要将这些运用起来,再花一周的时间,在网上阅读代码.这个任务初看会觉得很艰巨.我将直接把你丢到深水区呆几天,让你竭尽全力去读懂实实在在的 ...
- ModuleNotFoundError: No module named 'yaml'
ModuleNotFoundError: No module named 'yaml' 需要安装 pyyaml 包
- Selenium入门6 操作元素,获取元素属性
取元素的text,属性get_attribute,标签名tag_name 操作元素:send_keys输入,click点击,submit提交,clear清除输入 状态判断:is_display,is_ ...
- MyBatis的优缺点以及特点
特点: mybatis是一种持久层框架,也属于ORM映射.前身是ibatis. 相比于hibernatehibernate为全自动化,配置文件书写之后不需要书写sql语句,但是欠缺灵活,很多时候需要优 ...
- bootstarp v3 学习简记
1.快速设置浮动通过这两个class让页面元素左右浮动. !important被用来避免某些问题. <div class="pull-left">...</div ...
- 第33章 TIM—电容按键检测—零死角玩转STM32-F429系列
第33章 TIM—电容按键检测 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fir ...
- 顺序语句:GOTO和NULL语句
一 标号和GOTO 1 语法: PL/SQL中GOTO语句是无条件跳转到指定的标号去的意思.语法如下: GOTO label;......<<label>> /*标号是用< ...
- ReplaceChar
好吧,给个char的,替换单个字符.这样会快一些吧,这个是置换,连长度都不用了 bool ReplaceChar(char *str,const char src, const char dst){ ...