前言

突发奇想,想写一篇原型的文章,也可能是因为对原型有更深的理解吧,在这里做个记录,来记录下自己的理解加深下记忆。

总之,希望本文的内容能够对您的学习或者工作有所帮助。另,如果有任何的错误或者不足请指正!

创建对象有几种方法

js里说到原型,肯定离不开面向对象,说到面向对象肯定离不开对象,本文总结了大致3种创建对象的方法

  1. 字面量创建

  2. 显式的构造函数创建

  3. 使用Object.create()创建

原型、构造函数、实例、原型链

原型:函数都有prototype属性,是js默认添加的,prototype指向构造函数的原型对象,只有当函数是构造函数的时候,prototype才有意义

实例:只要是一个对象,都是实例

构造函数:构造函数是可以使用new运算符生成一个实例的函数就是构造函数,任何一个函数,只要被new使用了,都是构造函数

ps:原型有个构造器:constructor(构造器),指向是声明的构造函数

总结:

  1. 构造函数通过new和实例关联

  2. 构造函数通过prototype和原型对象关联

  3. 实例通过__proto__和原型对象关联

  4. 原型链是通过__proto__和prototype实现

  5. Object.prototype是原型链的顶端

先有鸡还是先有蛋??

弄懂了上面那些,我们来看看一个有趣的现像

    Function instanceof Object  // true
Object instanceof Function // true

回答这个问题前,我们需要了解一下Function.protype,因为它是导致Function instanceof Object和Object instanceof Function都为true的根本原因。

  1. Function.prototype是个不同于一般函数对象。

    1. Function.prototype像普通函数一样可以调用,但总是返回undefined;
    2. 普通函数实际上是Function的实例
  2. Object本身就是一个构造函数,是Function的实例,即Object.__proto__就是Function.prototype

我们通过代码来了解一下:


// 1.Function的构造器是它自身
Function.constructor=== Function; //true // 2.Object的构造器是Function(实际上所有函数的构造器都指向Function)
Object.constructor === Function; //true // 3.Object的__proto__指向Function的prototype
Object.__proto__ === Function.prototype; //true // 4.Function的__proto__指向Function的prototype
Function.__proto__ === Function.prototype //true // 5.Function.prototype的__proto__指向Object.protype
Function.__proto__.__proto__ === Object.prototype //true

O(∩_∩)O,通过这里,我想大概我们可以知道为什么会有这个神奇的现像了吧?

是谁创建了它(Object.prototype)呢??

    Object.prototype.__proto__===null //true

从这里可知,是null创造了一切,正如道德经所说:道生一,一生二,二生三,三生万物

instanceof的原理

我们再回过头来看先有鸡还是先有蛋的那个问题,造成这个现像的原因还是得归根于instanceof的运算规则。

instanceof的运算规则

w3c官方解释(传送门),还是一如既往的难懂 (lll¬ω¬)

我们用个简单的例子说明一下:


var Person = function (){}
var Student = function (){}
Student.prototype = new Person;
var gating = new Student() gating instanceof Student //true
gating instanceof Person //true

ps: instanceof会递归查找左边的原型链

总结:instanceof检测左侧的__proto__原型链上是否存在右侧的原型对象。

new运算符

从上我们可以了解到原型、构造函数、实例、原型链了,接下来了解下new运算符

说到new运算符,我们先看看下面这段代码:

    function Person(name){
this.name = name
}
var gating = new Person("gating")

很简单的一段代码,我们来看看new运算符是如何进行工作的呢?

我们可以把它拆分成3步:

  1. 创建一个新的对象,他继承于Person.prototype

  2. 构造函数Person被执行。相应的参数会被传入,同时this会指向这个新创建的对象。 tips:再不传递任何参数的情况下,new Person 等同于 new Person()

  3. 如果构造函数返回了一个“对象”,那么这个对象会取代整个new出来的结果。如果构造函数没有返回对象(通常也是这么做的, 不让其有返回值),那么new出来的结果为步骤1创建的对象

我们简单的通过代码实现一下new:


var new2 = function(fun){
var obj = Object.create(fun.prototype);
var o = fun.call(obj)
if(typeof o === 'object'){
return o
}else{
return obj
}
} var Student = function (){}
var gating = new2(Student) gating instanceof Student //true

最后,感谢各位观众老爷观看

浅谈js原型的更多相关文章

  1. 浅谈Js原型的理解

    一.js中的原型毫无疑问一个难点,学习如果不深入很容易就晕了!    在参考了多方面的资料后,发现解释都太过专业,对于很多还没有接触过面向对象    语言的小白来说,有理解不了里面的专有名词!如果你没 ...

  2. 37.js----浅谈js原型的理解

    浅谈Js原型的理解 一.js中的原型毫无疑问一个难点,学习如果不深入很容易就晕了!    在参考了多方面的资料后,发现解释都太过专业,对于很多还没有接触过面向对象    语言的小白来说,有理解不了里面 ...

  3. 浅谈JS中的!=、== 、!==、===的用法和区别 JS中Null与Undefined的区别 读取XML文件 获取路径的方式 C#中Cookie,Session,Application的用法与区别? c#反射 抽象工厂

    浅谈JS中的!=.== .!==.===的用法和区别   var num = 1;     var str = '1';     var test = 1;     test == num  //tr ...

  4. 浅谈JS之AJAX

    0x00:什么是Ajax? Ajax是Asynchronous Javascript And Xml 的缩写(异步javascript及xml),Ajax是使用javascript在浏览器后台操作HT ...

  5. 浅谈JS中的闭包

    浅谈JS中的闭包 在介绍闭包之前,我先介绍点JS的基础知识,下面的基础知识会充分的帮助你理解闭包.那么接下来先看下变量的作用域. 变量的作用域 变量共有两种,一种为全局变量,一种为局部变量.那么全局变 ...

  6. 浅谈 js 正则字面量 与 new RegExp 执行效率

    原文:浅谈 js 正则字面量 与 new RegExp 执行效率 前几天谈了正则匹配 js 字符串的问题:<js 正则学习小记之匹配字符串> 和 <js 正则学习小记之匹配字符串优化 ...

  7. 浅谈 js 字符串之神奇的转义

    原文:浅谈 js 字符串之神奇的转义 字符串在js里是非常常用的,但是你真的了解它么?翻阅<MDN String>就可以了解它的常见用法了,开门见山的就让你了解了字符串是怎么回事. 'st ...

  8. 浅谈 js 正则之 test 方法

    原文:浅谈 js 正则之 test 方法 其实我很少用这个,所以之前一直没注意这个问题,自从落叶那厮写了个变态的测试我才去看了下这东西.先来看个东西吧. var re = /\d/; console. ...

  9. 浅谈 js 数字格式类型

    原文:浅谈 js 数字格式类型 很多人也许只知道 ,123.456,0xff 之类的数字格式.其实 js 格式还有很多数字格式类型,比如 1., .1 这样的,也有 .1e2 这样的. 可能有人说这是 ...

随机推荐

  1. kali2020解决安装pip的问题

    在以前的版本中,我们需要安装pip时,只需要执行下面命令即可安装: apt-get install python-pip 但是在更新到2020.1以后,上面的命令安装会提示无法定位安装包的问题! 解决 ...

  2. AT命令集详解

    1.2 AT的优点. 命令简单易懂,并且采用标准串口来收发AT命令,这样对设备控制大大简化了,转换成简单串口编程了. AT命令提供了一组标准的硬件接口--串口.这个简化的硬件设计.较新的电信网络模块, ...

  3. Badboy脚本开发

    Badboy中的检查点 以sogo.com搜索为例演示,搜索Badboy 选中搜索框中的关键词----菜单“Tools”----“Add Assertion for Selection”添加检查点 2 ...

  4. Spark aggregateByKey函数

    aggregateByKey与aggregate类似,都是进行两次聚合,不同的是后者只对分区有效,前者对分区中key进一步细分 def aggregateByKey[U: ClassTag](zero ...

  5. vue 事件修饰符(阻止默认行为和事件冒泡)

    1. 原生js中,阻止事件冒泡,获取点击对象, e.stopPropagation(); 2. vue阻止事件冒泡@click.stop="show" <body> & ...

  6. 基于 abp vNext 和 .NET Core 开发博客项目 - 再说Swagger,分组、描述、小绿锁

    在开始本篇正文之前,解决一个 @疯疯过 指出的错误,再次感谢指正. 步骤如下: 删掉.Domain.Shared层中的项目引用,添加nuget依赖包Volo.Abp.Identity.Domain.S ...

  7. Gym101630L Laminar Family

    题目链接:https://cn.vjudge.net/problem/Gym-101630L 题目大意: 对于一个集合的集合,若其中任意两个集合 \(A\) 和 \(B\) 都满足下述三个条件之一:\ ...

  8. Istio 将被捐赠给开源基金会 | 云原生生态周报 Vol. 47

    作者 | 陈俊.徐迪.陈有坤.李鹏.敖小剑 业界要闻 1.Google Cloud CEO 表示将把 Istio 项目捐赠给基金会 Istio 项目找到了理想的发展方向: 捐赠给开源基金会. 2.Ko ...

  9. 接口参数校验(不使用hibernate-validator,规避大量if else)

    引言 编写接口时,常用的参数校验使用hibernate-validator注解+@@Validated注解进行参数校验.当遇到一些特殊场景或需求,需要自己对参数进行手动校验时,会出现以下问题: 不可避 ...

  10. 本地安装并运行http-server、browser-sync、webpack

    有一些自带命令的辅助开发.测试类的工具,官方都推荐全局安装,如果不想全局安装只想在某个项目下用该怎么办呢? 如http-server.browser-sync.webpack这种自带CLI的工具 使用 ...