• Jascript原型链以及Object和Function之间的关系


    先看一个简单的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

  • 相关阅读:
    Linux多cuda版本切换
    国庆节换头像热潮:国旗渐变微信头像和微信头像加上国旗!制作教程来了,你会了吗???
    《手把手教你》系列技巧篇(二十八)-java+ selenium自动化测试-处理模态对话框弹窗(详解教程)
    《手把手教你》系列技巧篇(二十七)-java+ selenium自动化测试- quit和close的区别(详解教程)
    《手把手教你》系列技巧篇(二十六)-java+ selenium自动化测试-浏览器操作(详细教程)
    《手把手教你》系列技巧篇(二十五)-java+ selenium自动化测试-FluentWait(详细教程)
    《手把手教你》系列技巧篇(二十四)-java+ selenium自动化测试-三大延时等待(详细教程)
    《手把手教你》系列技巧篇(二十三)-java+ selenium自动化测试-webdriver处理浏览器多窗口切换下卷(详细教程)
    《手把手教你》系列技巧篇(二十二)-java+ selenium自动化测试-webdriver处理浏览器多窗口切换上卷(详细教程)
    《将博客搬至CSDN》
  • 原文地址:https://www.cnblogs.com/liutianzeng/p/10438554.html
Copyright © 2020-2023  润新知