• 通俗易懂的理解js原型链


    js的原型链

    为什么需要原型链?

    • 为什么需要原型:在一些场景中,比如人类行为有些要打游戏,有些要上学,有些要工作,但同时他们都需要吃饭和睡觉,但如果把每个人吃饭睡觉私有化使用的话就有点浪费内存,这时候就可以把这些每个人都需要做的行为统一拿出来放到一个公共的空间,每个人都有权限访问它,这样就可以节省内存。而实现共享的,这个时候就用到了原型 prototype。可以将附加属性附加到它,这些属性将在其构造函数的所有实例之间共享。

    什么是原型链?

    • 了解原型链之前先来了解一下js创建对象的过程
      https://www.cnblogs.com/geekjsp/p/15807618.html

    • 访问一个对象时,js引擎内部的查找过程,会按以下顺序进行查找:

      • 1.首先在自身的对象查找,如果有,就返回。
      • 2.如果对象自身没有,就去对象所属的构造函数进行查找,如果有就返回。
      • 3.如果在对象所属的构造函数中没有找到,就去构造函数的原型(链)上进行查找。
      • 4.如果在整个原型链都查找完毕时,仍然找不到目标属性,就会返回undefined。
       
       function Bar() {
           this.color = "red"
       }
       
       Bar.prototype.color = "green";
       let obj = new Bar();
       obj.color = "blue";
       
       console.log(obj.color);    // blue
       
    
       demo2:印证上述第二点:
    
       function Bar() {
           this.color = "red"
       }
       
       Bar.prototype.color = "green";
       let obj = new Bar();
       
       console.log(obj.color);    // red
       
    
       demo3:印证上述第三点
    
       function Bar() {
       
       }
       
       Bar.prototype.color = "green";
       let obj = new Bar();
       
       console.log(obj.color);    // green
       
    
       demo4:印证上述第四点
    
       function Bar() {
       
       }
       
       let obj = new Bar();
       
       console.log(obj.color);    // undefined
    
      
    
    

    prototype和[[prototype]]有什么关系?

    其实[[prototype]]和__proto__意义相同,均表示对象的内部属性,其值指向对象原型。前者在一些书籍、规范中表示一个对象的原型属性,后者则是在浏览器实现中指向对象原型。
    
    prototype是函数才有的属性,Object没有
    

    原型链过程

    请看下面的代码片段:

    
       function Person(){}
       Person.__proto__==Function.prototype  //true
    
       let a={}
       a.__proto__==Object.prototype     //true
    
       let Teacher=new Person();
       Teacher.__proto__==Person.prototype //true
    
       --------------------------------------------------------
    
       function test99(){}
       test99.__proto__==Object.prototype
       //true
    
       test99.__proto__==Function.__proto__
       //false
    
      ---------------------------------------------------------
    
       var one = {x: 1};
       var two = new Object();
       one.__proto__ === Object.prototype // true
       two.__proto__ === Object.prototype // true
       one.toString === one.__proto__.toString // true
       说明 one.就是在one.__proto__.查找
    
      ---------------------------------------------------------
    
       let objP = function() {};
       let obj = new objP();
    
       创建一个obj对象  把obj对象的__proto__指向prototype  
       对象的__proto__属性是创建对象时自动添加的,默认值为其构造函数的prototype
    
       因此:
       objP.prototype.sayHell=function(str){console.log(str)}
       let obj = new objP();
       obj.__proto__   //{sayHell: ƒ, constructor: ƒ}
       obj.sayHell('搞懂js原型链')
       obj.方法名的时候会到__proto__上找因此会到objP.prototype
       --------------------------------------------------------
    
    
       function test666(){}
       let test7=new test666()
       test7.__proto__===test666.prototype
       //true
       test7.__proto__.__proto__===test666.prototype.__proto__
       //true
       test666.prototype.__proto__==Object.prototype
       //true
       Object.__proto__.__proto__
       //{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
       Object.__proto__.__proto__.__proto__
       //null
    
       --------------------------------------------------------
    
       
       var fn =function (){};
       prototype是在定义函数时自动添加的, 默认值是一个空Object对象
       fn.prototype
       // {constructor: ƒ}
       // constructor: ƒ Person()
       // [[Prototype]]: Object
    
       可以添加属性和方法,这些属性和方法将在其构造函数的所有实例之间共享   
       fn.prototype.name='wen';
       fn.prototype.age='18';
    
       var obj1=new fn();
       var obj2=new fn();
       console.log(obj1.name);
       console.log(obj2.age);
    
       obj1.constructor.prototype==fn.prototype
    
       obj1.name的查找过程:
       obj1> 构造函数fn > fn.__proto__>fn.__proto__.__proto__>null 返回undefined
    
       --------------------------------------------------------
    
    
    
    

    原型链总结

    • 大多数情况下,__proto__可以理解为“构造函数的prototype”。

    • 每当您在 JavaScript 中访问对象的属性时,它首先会检查该属性是否在对象内部可用。如果不是,它检查它的原型对象。如果有返回。否则,它将检查该属性是否存在于原型的原型中,如果不存在则再次检查该属性是否存在于原型的原型中,依此类推。

    那么它会以这种方式检查多长时间?__proto__如果在任何点找到该属性或在任何点的值为null或,它将停止undefined。然后它会抛出一个错误,通知你它无法找到你正在寻找的属性。(https://www.freecodecamp.org/news/all-you-need-to-know-to-understand-javascripts-prototype-a2bff2d28f03/)

    console.log(Object.prototype.proto===null);//true

    原型链原理图

  • 相关阅读:
    你知道Synchronized底层实现原理嘛
    一篇搞定Java集合类原理
    lsp都要会的内存模型
    Sql Server 查询优化
    使用Windows的mstsc远程桌面连接到Ubuntu图形界面(AWS上安装的Ubuntu系统)
    AWS EC2实例Ubuntu系统设置root用户密码并使用root/ubuntu用户登录
    安装mysql.zip文件教程(包含常见问题修复)
    DevExpress GridControl小结
    C#开发必会
    C# 错误集锦
  • 原文地址:https://www.cnblogs.com/geekjsp/p/15808602.html
Copyright © 2020-2023  润新知