资讯专栏INFORMATION COLUMN

嗟乎原型链

hellowoody / 1736人阅读

摘要:也就是说对象都是函数创建的而属性是为了继承而生的,所有只需要函数有就够了构造函数的属性指向的是一个对象,这个对象就是我们说的原型我们知道去的路,那也要知道回来的路吧就是回来的路。

构造函数与实例
function Foo() {};

let instance = new Foo();

构造函数其实就是一个函数,只不过我们约定俗成:构造函数首字母大写

在江湖上混,有些黑话还是要遵守的

实例就是用new操作符执行构造函数返回的对象

prototype

js里面一切皆对象,所以函数也是一种对象

既然是对象就可以有属性,prototype就是函数的内置属性,而且只有函数才有prototype属性

为什么只有函数才有prototype属性?

因为所有的函数都可以充当构造函数,而所有的对象都是构造函数创建的。也就是说对象都是函数创建的

prototype属性是为了继承而生的,所有只需要函数有就够了

constructor

构造函数的prototype属性指向的是一个对象,这个对象就是我们说的原型

我们知道去的路,那也要知道回来的路吧!

constructor就是回来的路。它指向原型所在的构造函数,和prototype的方向正好相反

有一个问题

function Foo() {};

let instance = new Foo();

console.log(instance.constructor); // function Foo() {};

为什么实例的constructor属性也指向构造函数?

其实实例的constructor属性不是它自己的,是原型继承过来的

proto

__proto__是实例的属性,因为实例是一个对象,而所有对象都是函数创建的,于是所有对象都有__proto__属性

实例的__proto__属性指向它的构造函数的原型

一家人

有了这三个属性,实例、构造函数、原型就有了可以互相找到对方的路,从此这一家人互相之间再也不会失了音信

function Foo() {};

let instance = new Foo();

console.log(Foo.prototype); // 原型

console.log(Foo.prototype.constructor); // 构造函数

console.log(instance.__proto__); // 原型

实例有点可怜,它的联系是单向的,如果实例不主动呼出的话,构造函数和原型是找不到它的

Foo的构造函数

那么构造函数Foo的构造函数又是谁呢?

console.log(Foo.__proto__.constructor); // function Function() { [native code] }

看到那串[native code]没?它表示到这里止步,否则,你就知道的太多了

总之,这个function Function() { [native code] }略屌

Foo的构造函数的原型
console.log(Foo.__proto__); // function() { [native code] }

一样,我们得到一个这样的东西function() { [native code] }

Foo.prototype的构造函数
console.log(Foo.prototype.__proto__.constructor); // function Object() { [native code] }

也带了一串[native code],但至少我们知道它是个函数

再往上走两步
console.log(Foo.prototype.__proto__.constructor.__proto__.constructor); // function Function() { [native code] }

这是Foo.prototype的构造函数的构造函数,哟,见到老朋友了!

再再往上走两步
console.log(Foo.prototype.__proto__.constructor.__proto__.constructor.__proto__.constructor); // function Function() { [native code] }

诶,见鬼了!往上怎么还是这哥们?

你要是不晕,其实还可以再往上走两步,仍然是这哥们

自己生自己,是不是有点色即是空,空即是色的味道?

之前说了,所有对象都是函数创建的,这哥们就是函数始祖,是女娲用泥捏出来的

见到始祖,啥也别说,顶礼膜拜吧

Foo.prototype的构造函数的原型
console.log(Foo.prototype.__proto__); // {...}

打印出来是一个有一堆属性的对象

Foo的原型是由Object构造的,所以上面打印出来的就是Object.prototype

再往上走两步
console.log(Foo.prototype.__proto__.__proto__.constructor); // Uncaught TypeError: Cannot read property "constructor" of null

诡异的事情发生了,怎么会报错呢?

原因在于,Foo.prototype.__proto__.__proto__指向null,也就是Object的原型的原型是null

那么,Object的原型并不是构造函数创建的,因为报错了嘛!难道是石头缝里蹦出来的?

燧人之世,大迹在雷泽,华胥履之,而生伏羲。是不是感觉越来越像神话了

龙生龙,凤生凤

天灵灵,地灵灵,来一张符咒防身

看到没有,只要是(构造)函数,最终会走向Function,进而循环;只要是原型(对象),最终会走向Object,进而走向null

Function是爹,说Object是娘,你有意见吗?

instanceof
console.log(instance instanceof Foo); // true

instanceof的原理是:沿着instance__proto__上溯,同时沿着Fooprototype上溯,如果能相遇,就返回true,如果始终无法相遇,就返回false

来看一个例子

console.log(Function instanceof Object); // true

console.log(Object instanceof Function); // true

再次说明了,Function可不是像Array, Number, String, Boolean一样的小弟,它和Object有说不清道不明的关系

其实原型链并不长

乍一听原型链,好像总也望不到头,其实走两步就到死胡同了

没那么可怕

继承

原型链是怎么继承的呢?

再回过头去看看符咒

如果一个对象,它既是谁的原型,又是谁的实例,那么它就是原型链上的一个神经元,原型链就是通过这些神经元沟通起来的

A的原型是B的实例,好理解吧!

我们也可以手动继承

function Parent() {
    this.name = "Abby";
}

Parent.prototype.getName = function() {
    console.log(this.name);
}

function Child() {

}

Child.prototype = new Parent();

var grandson = new Child();

console.log(grandson.getName()); // Abby

当然继承有很多种模式,这里不展开

github原文地址

嗟乎原型链

github博客

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

转载请注明本文地址:https://www.ucloud.cn/yun/89753.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

发表评论

0条评论

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