• 原型与原型链


     一、原型:prototype

    1.什么是原型?

    javascript常被描述为一种基于原型的语言(每个对象都拥有一个原型对象

    当访问一个对象的属性时,它不仅在该对象上寻找,还会寻找该对象的原型,以及该对象原型的原型,层层向上,直到找到或者到达原型链的末尾

    函数可以有属性,每个函数都有一个特殊的属性叫做原型prototype

    1. function Fn(){}
    2. console.log( Fn.prototype );
    3. // 控制台输出
    4. /* {
    5. constructor: ƒ Fn(),
    6. __proto__: {
    7. constructor: ƒ Object(),
    8. hasOwnProperty: ƒ hasOwnProperty(),
    9. isPrototypeOf: ƒ isPrototypeOf(),
    10. propertyIsEnumerable: ƒ propertyIsEnumerable(),
    11. toLocaleString: ƒ toLocaleString(),
    12. toString: ƒ toString(),
    13. valueOf: ƒ valueOf()
    14. }
    15. }
    16. */

    上面的这个对象,就是大家常说的原型对象

    可以看到,原型对象有一个自有属性constructor,这个属性指向该函数,如下图关系展示

    2.函数的prototype属性

    每个函数都有一个prototype属性,它默认指向一个Object对象(即为:原型对象)

    原型对象中有一个属性constructor,它指向函数对象

    3.给原型对象添加属性(一般都是方法)

    作用:函数的所有实例对象自动拥有原型中的属性 

    4.原型对象有一个属性constructor,它指向函数对象

    二、显示原型与隐式原型

    1.每个函数function都有一个prototype,即显示原型(属性)

    2.每个实例对象都有一个_proto_,可称为隐式原型(属性)

    3.对象的隐式原型的值为其对应构造函数的显示原型的值

    4.内存结构

    1. //定义构造函数
    2. Function Fn(){ //内部语句:this.prototype={}
    3. }
    4. //每个函数function都有一个prototype,即显示原型属性,默认指向一个空的Object对象
    5. console.log(Fn.prototype)
    6. //创建实例对象
    7. //每个实例对象都有一个_proto_,可称为隐式原型
    8. var fn=new Fn()//内部语句:this._proto_===Fn.prototype
    9. console.log(fn._proto_)
    10. //对象的隐式原型的值为其对应构造函数的显示原型的值
    11. console.loG(fn._proto_===Fn.prototype)
    12. //给原型添加方法
    13. Fn.prototype.test=function(){
    14. console.log('test()')
    15. }
    16. //通过实例调用原型的方法
    17. fn.test()

    5.总结:

    函数的prototype属性:在定义函数时自动添加的,默认值是一个空Object对象

    对象的_proto_属性:创建对象时自动添加的,默认值为构造函数的prototype属性值

    程序员能直接操作显示原型,但不能直接操作隐式原型(ES6之前)

    三、原型链

    1.原型链的概念

    原型对象也可能拥有原型,并从中继承方法和属性,一层一层,依次类推。这种关系就形成了原型链(这也就是为何一个对象会拥有定义在其他对象中的属性和方法)

    在对象实例和他的构造器之间建立一个连接(它是_proto_属性,是从构造函数的prototype属性派生的),之后通过溯原型链,在构造器中找到这些属性和方法

    2.原型链:访问一个对象的属性时

    (1)先在自身属性中查找,找到返回

    (2) 如果没有,则再沿着_proto_这条链向上查找,找到返回

    (3) 如果最终没有找到,返回undefined

    别名:隐式原型链

    作用:查找对象的属性(方法)

    1. function Fn(){
    2. this.test1=function(){
    3. console.log('test1()')
    4. }
    5. }
    6. Fn.prototype.test2=function(){
    7. console.log('test2()')
    8. }
    9. var fn=new Fn()
    10. fn.test1()
    11. fn.test2()
    12. console.log(fn.toString())

    3.构造函数/原型/实例对象的关系

    (1) 函数的显示原型指向的对象默认是空的Object对象(但Object不满足) 

    (2)所有的函数都是Function的实例(包含Function)

    (3)Object的原型对象是原型链尽头 

    (4)实例对象的隐式原型等于构造函数的显示原型属性,任何函数都是new Function产生的

    小结:

    1. function Person(name) {
    2. this.name = name
    3. this.age = 20
    4. this.sayName = function() {
    5. console.log(this.name)
    6. }
    7. }
    8. // 创建实例
    9. let person = new Person('CSDN')

    (1)__proto__作为不同对象之间的桥梁,用来指向创建它的构造函数的原型对象

    (2)每个对象的__proto__都是指向它的构造函数的原型对象的prototype

    person1.__proto__ === Person.prototype

    (3)构造函数是一个函数对象,都是通过Function构造器产生的

    Person.__proto__===Function.prototype

    (4)原型对象本身是一个普通对象,而普通对象的构造函数都是Object

    Person.prototype.__proto===Object.prototype

    (5)刚刚上面说了,所有的构造器都是函数对象,函数对象都是Function构造产生的

    Object.__proto===Function.prototype

    (6)Object的原型对象也有__proto__属性指向null,null是原型链的顶端

    Object.prototype.__proto__ === null

    tip:

    • 一切对象都是继承自Object对象,Object对象直接继承根源对象null
    • 一切的函数对象(包括Object对象),都是继承自Function对象
    • Object对象直接继承自Function对象
    • Function对象的__proto__会指向自己的原型对象,最终还是继承自Object对象

    4.原型继承:

    (1)构造函数的实例对象自动拥有构造函数原型对象的属性

    (2) 利用的就是原型链、

    5.原型属性问题

    (1)读取对象的属性值时,会自动到原型链中查找

    (2)设置对象的属性值时,不会查找原型链,如果当前对象中没有此属性,直接添加此属性并设置其值

    (3)方法一般定义在原型中属性一般通过构造函数定义在对象本身

    6.探索instanceof

    (1)instanceof是如何判断的?

       表达式:B  instanceof  A

       如果A函数的显示原型对象在B对象的原型链上,返回trur,否则返回false

    (2)Function是通过new自己产生的实例

  • 相关阅读:
    应用商店的ASO和搜索引擎的SEO的区别
    【机器学习-黑马程序员】人工智能、机器学习概述
    推荐一个AI人工智能技术网站(一键收藏,应有尽有)
    详解【计算机类&面试真题】军队文职考试——第5期:什么是网桥?防火墙的端口防护是什么?| ARP地址解析协议的工作原理 | TCP的三次握手过程,若两次握手可以吗? | 差错检测及常见的差错检测技术
    监控易在大数据运维中的应用与实践
    如何监控Tomcat的性能?
    这8大优势你都不知道,你敢说你精通单元测试?
    应该了解的数据库系统高性能利器-WAL
    pycharm连接服务器
    [JavaScript 刷题] 搜索 - 最短单词路径, leetcode 127
  • 原文地址:https://blog.csdn.net/m0_61478092/article/details/133953227