资讯专栏INFORMATION COLUMN

原型链

gaomysion / 1243人阅读

摘要:不过,从编程习惯上,我们应该尽量让对象的指向其构造函数,以维持这个惯例总结原型和原型链是实现继承的一种模型原型链是靠形成的,它在其中的作用属于连接的线

原型链概念
每个构造函数内部都会有一个(constructor,prototype原型对象),而且都会有一个内置树形__proto__属性用于指向创建它函数对象的prototype原型,当然原型对象也会有__proto__属性,源源不断的指向关联,就形成了一个圆环,形成了原型链
原型prototype对象

函数对象

function f() {
}
console.log(f.prototype)


我们创建了一个函数f,通过打印它的原型对象,我们会得到一个对象,里面包含一个constructor指向自己本身的指针,还有一个内置__proto__属性

console.log(f.prototype.__proto__)


那我们再看看它的内置属性指向了哪里,我们可以很清楚的看到constructor指向了Object,而它还内置了toString()和valueOf()方法,这到了哪里已经不用我多说了吧

console.log(f.prototype.__proto__.__proto__)

那我们再继续寻找往下找呢,我们会得到null,此可以得出结论,请看下面图解

普通对象

let obj = {}
console.log(obj.prototype) // undefined

当然普通对象是没有原型对象的

作用
原型链就是为了实现继承

例子

function Father() {
    this.name = "aaa"
}

Father.prototype.f1 = function () {
    alert(this.name)
}

// 子函数 继承父
function Son(name) {
    Father.call(this, name)
}

// 我认为继承父
Son.prototype = Object.create(Father.prototype)

// minix 继承多种 Object.assign(1,2,3)
Son.prototype.constructer = Son   //构造器指向

// 重写父方法,改变数据变化,并且不会覆盖父方法,这里称为多态
Son.prototype.f1 = function () {
    console.log(this.name)
}

var S1 = new Son()
S1.f1() // 调用 aaa

检查原型和实例的关系

第一种使用 instanceof 操作符
    console.log(S1 instanceof Object)//true
    console.log(S1 instanceof Father)//true
    console.log(S1 instanceof Son)//true
    
上面检测S1这个实例是否属于Object,Father,Son,结果都返回了true,有些小伙伴会疑问为什么我new的是Son,它还会属于Father,因为Son.prototype = Object.create(Father.prototype)这段代码已经将父的原型给了子了,并且又constructer指向了子函数,这相当于已经继承成功




第二种使用isPrototypeOf

作用:检测一个对象是否是另一个对象的原型。或者说一个对象是否被包含在另一个对象的原型链中

    console.log(Object.prototype.isPrototypeOf(S1))  //true
    console.log(Father.prototype.isPrototypeOf(S1))  //true
    console.log(Son.prototype.isPrototypeOf(S1))   //true
    
查找
Function.__proto__ === Function.prototype

每个函数声明之后都会生成一个函数对象,这正如我们说的那样函数的__proto__是指向它自己的原型的

Function.prototype.__proto__  === Object.prototype

函数原型再向上查找是什么,它们直接通过什么连接,当然是__proto__,它指向的则是Object.prototype

Object.prototype.__proto__  === null

然后再去查找Object.prototype,它会等于null,因为已经到达最底层了,这个记住就好

constructor属性
constructor属性不影响任何JavaScript的内部属性。
instanceof检测对象的原型链,通常你是无法修改的

constructor其实没有什么用处,只是JavaScript语言设计的历史遗留物。
由于constructor属性是可以变更的,所以未必真的指向对象的构造函数,
只是一个提示。不过,从编程习惯上,我们应该尽量让对象的constructor指向其构造函数,以维持这个惯例
总结
原型和原型链是JS实现继承的一种模型
原型链是靠__proto__ 形成的,它在其中的作用属于连接的线

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102899.html

相关文章

  • 《javascript高级程序设计》笔记:原型图解

    摘要:不理解没关系,下面会结合图例分析上一篇高级程序设计笔记创建对象下一篇高级程序设计笔记继承参考之原型链的解读三张图搞懂的原型对象与原型链继承与原型链 文章直接从原型图解开始的,如果对一些概念不太清除,可以结合后面几节查看 1. 图解原型链 1.1 铁三角关系(重点) function Person() {}; var p = new Person(); showImg(https://s...

    vspiders 评论0 收藏0
  • 如何理解JavaScript的原型原型

    摘要:之前有朋友问怎么去理解原型和原型链的问题。理解原型链的小技巧将箭头视作泛化子类到父类关系那么图中所有的虚线将构成一个继承层级,而实线表示属性引用。原型链是实现继承的重要方式,原型链的形成是真正是靠而非。 之前有朋友问怎么去理解原型和原型链的问题。这个问题,在面试中,很多同学经常都会遇到。这里给大家讲讲,方便大家记忆。 JavaScript的特点JavaScript是一门直译式脚本...

    xuexiangjys 评论0 收藏0
  • 如何理解JavaScript的原型原型

    摘要:之前有朋友问怎么去理解原型和原型链的问题。理解原型链的小技巧将箭头视作泛化子类到父类关系那么图中所有的虚线将构成一个继承层级,而实线表示属性引用。原型链是实现继承的重要方式,原型链的形成是真正是靠而非。 之前有朋友问怎么去理解原型和原型链的问题。这个问题,在面试中,很多同学经常都会遇到。这里给大家讲讲,方便大家记忆。 JavaScript的特点JavaScript是一门直译式脚本...

    adie 评论0 收藏0
  • 【5】JavaScript 函数高级——原型原型深入理解(图解)

    摘要:探索是如何判断的表达式如果函数的显式原型对象在对象的隐式原型链上,返回,否则返回是通过自己产生的实例案例案例重要注意的显示原型和隐式原型是一样的。面试题测试题测试题报错对照下图理解 原型与原型链深入理解(图解) 原型(prototype) 函数的 prototype 属性(图) 每个函数都有一个prototype属性,它默认指向一个Object空对象(即称为:原型对象) 原型对象中有...

    马龙驹 评论0 收藏0
  • JS基础-原型原型真的不能一知半解

    摘要:原型链和对象的原型是对象实例和它的构造函数之间建立的链接,它的值是构造函数的。对象的原型根据上文提到的构造调用函数的时候会创建一个新对象,自动将的原型指向构造函数的对象。 showImg(https://segmentfault.com/img/remote/1460000020185197); JS的原型、原型链一直是比较难理解的内容,不少初学者甚至有一定经验的老鸟都不一定能完全说清...

    changfeng1050 评论0 收藏0
  • JavaScript面向对象---原型继承

    摘要:因为这造成了继承链的紊乱,因为的实例是由构造函数创建的,现在其属性却指向了为了避免这一现象,就必须在替换对象之后,为新的对象加上属性,使其指向原来的构造函数。这个函数接收两个参数子类型构造函数和超类型构造函数。 最近一直在研究js面向对象,原型链继承是一个难点,下面是我对继承的理解以下文章借鉴自CSDN季诗筱的博客 原型链继承的基本概念: ES中描述了原型链的概念,并将原型链作为实现...

    vspiders 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<