先看一个简单的function变量

function fun1(name) {
this.name = name;
} console.log("fun1", fun1)

从结果可以看到定义一个function,它里边所含有的内容这六个属性是每个function所必有的,直接看第五个prototype(注意prototype是一个对象)就是传说中的原型(本文只称它为prototype,也叫显性原型),第六个属性是灰色的并且用尖括号括起来,在以前版本的浏览器它有另外一个名字叫__proto__(也叫隐形原型)。

如果大家去实验一下就会发现,每个对象都会有__proto__这个属性,但一般情况下只有声明function的变量(例如上图中的fun1)才会有(自动生成)prototype这个属性,所以总结一下是对象只有隐形原型,而function既有隐形原型(_proto_)又有显性原型(prototype),因为函数在js里面既是函数也是对象。

可以看到在 prototype里有两个属性constructor和__proto__,在前面我们说过prototype是一个对象和每个对象都会有__proto__这个属性,因此prototype也是有__proto__这个属性;constructor(构造方法)这个属性是在生成prototype时自动生成的属性,其指向函数本身(在申明函数时,js自动创建该函数的peototype属性)。

function fun1(name) {
this.name = name;
} var temp = new fun1("");
var obj = new Object;
console.log(temp.__proto__ === fun1.prototype)//true
console.log(fun1.__proto__===Function.prototype)//true
console.log(obj.__proto__ === Object.prototype)//true

总结一下:

所有对象都有__proto__属性,是用来通过__proto__找到它的原型即prototype,function声明的变量的__proto__指向Function的prototype,其它对象的__proto__指向Object的prototype
function声明的变量、Function和Object都有prototype, 有prototype的东西可以产生实例(即可以作为new 后边的值)。 
prototype它是一个对象(在声明函数变量是在函数内部由js自动创建),因此它也有__proto__,并且指向Object的prototype。

Function和Object非常特殊,我们来具体分析

首先看一下Function里的东西

console.log("Function", Function);
console.log("Function.__proto__", Function.__proto__)

从控制台的打印可以明显的看出Function的__proto__指向了它自己的prototype

接下里看Object(Object里有很多其它的东西,为了简洁我直接打印Object的prototype)

console.log("Object.prototype", Object.prototype)
console.log("Object.__proto__", Object.__proto__)

Object的prototype和Function的prototype的__proro__指向是相同的如下图:

综上可以看出Object的__proto__指向Function的prototype,而Object的prototype并没有灰色的<prototype>即__proto__,即它是一切之源。

console.log("Object.prototype.__proto__", Object.prototype.__proto__)

我将Object的prototype称为源型,下面我给出我个人对这些现象的解释:

源型是js的内置的一段代码,所有所有通过这个源型创造出的都是object,第一步先创造出Function的prototype,因此这个prototype的__proto__指向源型,然后再通过这个prototype造出Function,因此Function的__proto__指向它自己的prototype,然后用Function造出Object,因此Object的__proto__指向Function的prototype,然后js直接将Object的prototype替换为源型。

并且我认为js里判断继承(即A instanceof B)是沿着__proto__往下走,首先要求B必须有prototype属性且必须是一个对象(否则会浏览器会报 'prototype' property of B is not an object),判断时先判断A的__proto__是否和B的prototype指向是否相同(即===结果为true),若相同则返回true,若不相同则判断A的__proto__指向属性里是否还有__proto__属性,若有则进行再次进行判断指向是否相同,直到找到源型,它的__protot__为null,返回false

为了证明只要A的__protot__和B的prototype指向相同就返回true,给了如下测试:

var obj = new Object;
function fun () {};
console.log(obj instanceof fun);
var temp = new Object
fun.prototype = temp
obj.__proto__ = temp;
console.log(obj instanceof fun)

有点颠覆三观不过习惯就好。

下面用我的结论来解释下边四个现象:

console.log(Function instanceof Function)
console.log(Function instanceof Object)
console.log(Object instanceof Function)
console.log(Object instanceof Object)

Function的__proto__和Function的prototype指向相同,因此返回true,
Function的__proto__和Function的prototype指向指向相同,Function的prototype的__protot__和Object的prototype指向相同,因此返回true。
Object的__proto__和Function的prototype指向相同(因为Object就是以Function为模板创造的),因此返回true。
Object的__proto__指向Function的prototype,Function的prototype的__proto__指向Object的prototype,这个prototype是属于Object(饶了一圈),因此返回true。
只要高清内部原理,理解instanceof就非常简单

下面再来一个小测试:

var obj = new Object;
obj.__proto__ = Function.prototype;
console.log(obj instanceof Function)//true

总结:prototype是原型,__proto__所指向的以及其后的所有prototype称为原型链。“js里一切皆对象”倒不如所是js里的所有对象都是由“源型”生成。

原文:https://blog.csdn.net/backee/article/details/83378772

Jascript原型链以及Object和Function之间的关系的更多相关文章

  1. JavaScript原型链以及Object,Function之间的关系

    JavaScript里任何东西都是对象,任何一个对象内部都有另一个对象叫__proto__,即原型,它可以包含任何东西让对象继承.当然__proto__本身也是一个对象,它自己也有自己的__proto ...

  2. JS原型的问题Object和Function到底是什么关系

    var F = function(){}; Objcert.prototype.a = function(){}; Function.prototype.b = function(){}; F 既能访 ...

  3. JavaScript中的 原型 property 构造函数 和实例对象之间的关系

    1 为什么要使用原型? /* * javascript当中 原型 prototype 对象 * * */ //首先引入 prototype的意义,为什么要使用这个对象 //先来写一个构造函数的面向对象 ...

  4. Function、Object、Prototype 之间的关系解析

    前提:js中所有的内置对象都是Function 的实例. 例如:Array\String\Number... 等 原理剖析: 对象属性搜索的原理就是按照对象的 __proto__ 属性进行搜索,直到_ ...

  5. type、object、class之间的关系

    class Foo: pass print(type(int)) # <class 'type'> print(type(str)) # <class 'type'> prin ...

  6. 详解Javascript中的原型与原型链

    目录 知识点 参考资料 结束语 知识点 面向对象编程 我们熟悉的Java和C#里,面向对象的两个基本概念是类class和实例instance,而ES6以前的Javascript并没有设计class. ...

  7. Object instanceof Function和Function instanceof Object

    首先需要确定的是,instanceof是根据原型链来判断是否为某引用类型的实例.所以需要明白Object和Function之间的关系,以下为引用某博客的图片,阐述了javascript对象体系的关系 ...

  8. 为什么Object.prototype在Function的原型链上与Function.prototype在Object的原型链上都为true

    关于javascript的原型链有一个问题我一直很疑惑:为什么 Function instanceof Object 与 Object instanceof Function都为true呢? Func ...

  9. JS高级——Function原型链

    基本概念 1.函数可以通过Function new出来,那么Function可以被称作构造函数,被new出来的函数可以被称为一个对象 2.Function既然是构造函数,那么肯定也有原型,它的原型是一 ...

随机推荐

  1. laravel 安装配置前准备

    Laravel 框架使用 Composer 来管理其依赖性.所以,在你使用 Laravel 之前,你必须在你电脑上是否安装了 Composer.最简单的获取Composer的方式就是百度之,百度关键字 ...

  2. laravel M层

    目录 App\Models   没有就自己创一个 创建对应控制器的php文件,首字母大写 <?php namespace App\Models; use Illuminate\Database\ ...

  3. Unity亚洲开发者大会会议简录之技术篇,Profiler的一些参数的意思

    2014Unity亚洲开发者大会会议简录之技术篇 拖公司的福,有幸去了一趟北京参加了一场Unity3D的交流盛宴,在为期两天的时间内,不仅有着技术上收获,也有心灵上的震撼.现在先来说说技术方面的一些比 ...

  4. css 三种引用方式

    内联式 代码 <!doctype html> <html lang="en"> <head> <meta charset="UT ...

  5. performSegueWithIdentifier 不生效的解决办法

    相信很多人都会遇到这样的需求: APP 打开以后,判断用户是否登录,如果未登录,就跳转到登陆页. 今天我也遇到了这个需求,发现我封装的一个 `func checkLoginStatus()` 放在 ` ...

  6. GitHub使用方法(初级)

    [初识Github] Git 是一个分布式的版本控制系统,最初由Linus Torvalds编写,用作Linux内核代码的管理.在推出后,Git在其它项目中也取得了很大成功,尤其是在Ruby社区中.目 ...

  7. 01 | VIM基础攻略

    启动 vim 后,vim 处于 normal 模式. Step One: "i" -> insert 模式, ESC -> normal 模式: "x&quo ...

  8. scrapy的中间件Downloader Middleware实现User-Agent随机切换

    scrapy的中间件Download Middleware实现User-Agent随机切换   总架构理解Middleware 通过scrapy官网最新的架构图来理解: 从图中我们可以看出,在spid ...

  9. laravel配合swoole使用总结

    最近对接硬件做了两个项目,用到了swoole 第一个是门禁系统,需要远程开门.离线报警.定时开门.离线刷卡等功能 1.远程开门: 目前用cli创建个临时客户端连接服务端发送命令,服务端处理完成后客户端 ...

  10. Elasticsearch之探索集群信息

    REST API 启动并运行了节点和集群,下一步是了解如何与它进行通信.elasticsearch提供了一个非常全面和强大的REST API,可以使用它与集群进行交付. 使用API完成以下: • 检查 ...