前言

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

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

创建对象有几种方法

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. SDK,JDK,API的区别

    [基础概念] 先留一波传送门: SDK:软件开发工具包(外语全称:Software Development Kit)一般都是一些软件工程师为特定的软件包.软件框架.硬件平台.操作系统等建立应用软件时的 ...

  2. python --分隔符split()

    描述: python split()是通过指定分隔符对字符串进行切片,且可以指定分隔n+1个字符串. 语法: str.split(str="",num=string.count(s ...

  3. watch 和 计算属性

    作者:纵横链接:https://www.zhihu.com/question/55846720/answer/331760496来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...

  4. 简单mysql存储过程

    直接上代码: CREATE DEFINER=`root`@`localhost` PROCEDURE `sos`( ) BEGIN -- 创建一个临时表 DROP TABLE IF EXISTS fi ...

  5. webpack使用babel

    几个月没用webpack都忘了好多了. webpack构建前端,使用时除了entry/output,就是plugins和module.loaders,还有本地测试的devServer. npm ins ...

  6. angular2 + bootstrap +jquery 实例

    一.Create a project process: 1.use Angular CLI to create an Angular Project "demo": need th ...

  7. HTML新特性--canvas绘图-文本

    一.html5新特性--canvas绘图-文本(重点) #常用方法与属性 -ctx.strokeText(str,x,y);   绘制描边文字(空心) str:绘制文本 x,y:字符串左上角位置(以文 ...

  8. MySQL慢查询优化(线上案例调优)

    文章说明 这篇文章主要是记录自己最近在真实工作中遇到的慢查询的案例,然后进行调优分析的过程,欢迎大家一起讨论调优经验.(以下出现的表名,列名都是化名,实际数据也进行过一点微调.) PS:最近做了一个面 ...

  9. 万字长文!一次性弄懂 Nginx 处理 HTTP 请求的 11 个阶段

    Nginx 处理一个 HTTP 请求的全过程 前面给大家讲了 Nginx 是如何处理 HTTP请求头部的,接下来就到了真正处理 HTTP 请求的阶段了.先看下面这张图,这张图是 Nginx 处理 HT ...

  10. Spring Boot在Docker上的部署

    一.准备工作 1.1 安装Docker环境 Docker 给旧版本的WIN系统提供的是Docker Toolbox下载(https://docs.docker.com/toolbox/overview ...