先看一个简单的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. 骨骼蒙皮动画(SkinnedMesh Animation)的实现

    http://blog.csdn.net/zjull/article/details/11529695 1.简介 骨骼蒙皮动画,简称骨骼动画,因其占用磁盘空间少并且动画效果好被广泛用于3D游戏中,它把 ...

  2. Unity 2D骨骼动画2:创建真实动画

    http://bbs.9ria.com/thread-401781-1-1.html 在这个系列,我们将关注Unity引擎提供的基于骨骼动画工具.它的主要思想是为了把它应用到你自己的游戏来介绍和教基本 ...

  3. suse 11入门学习

    1 去掉显示隐藏文件的默认配置 vi /etc/bash.bashrc 找到 ; then LS_OPTIONS="-A -N $LS_OPTIONS -T 0" else LS_ ...

  4. 51Nod 1134 最长递增子序列(动态规划O(nlogn))

    #include <iostream> #include <algorithm> #include <stdio.h> #define MAXN 50010 usi ...

  5. .Net Core应用框架Util介绍(一)转

    回顾 2015年,正当我还沉迷于JQuery + EasyUi的封装时,突然意识到技术已经过时. JQuery在面对更加复杂的UI需求时显得力不从心,EasyUi虽然组件比较完善,但界面风格老旧,响应 ...

  6. STP-2-三个选择

    1.选择根交换机 2.确定根端口 3.确定指定端口     1.选择根交换机   stp中只有一台交换机能成为根(Root),每台交换机按自己的STP逻辑,先发一个hello称自己为根,如果收到了比自 ...

  7. [模板]manacher

    這麼簡單的算法現在才學...... https://segmentfault.com/a/1190000008484167?utm_source=tag-newest#articleHeader3 h ...

  8. TensorFlow 模型保存/载入

    我们在上线使用一个算法模型的时候,首先必须将已经训练好的模型保存下来.tensorflow保存模型的方式与sklearn不太一样,sklearn很直接,一个sklearn.externals.jobl ...

  9. Codeforces Round #533(Div. 2) D.Kilani and the Game

    链接:https://codeforces.com/contest/1105/problem/D 题意: 给n*m的地图,最多9个人,同时有每个人的扩张次数(我开始以为是直线扩张最大长度..实际是能连 ...

  10. siege官方文档(译)(二)

    WHY DO I NEED IT? Siege was written for both web developers and web systems administrators. siege是为了 ...