资讯专栏INFORMATION COLUMN

JS面向对象之二 【原型链】(对象和对象之间的关系)

Jochen / 2446人阅读

摘要:面向对象之二原型链对象和对象之间的关系注意这个系列文章要经常站在之父的视角去思考。思考问题我们都知道都属于那么既然他们都是对象一定有某些相同之处吧对象和对象之间有什么关联呢如果说你没有思考过这个问题那么可以换一个更具体的问题。

JS面向对象之二 【原型链】(对象和对象之间的关系)

注意这个系列文章,要经常站在JS之父的视角去思考。

牢记我们的需求,我要在JS没有class的情况下,那么利用JS现有的东西,搞出类似class的东西。

回一下JS有什么? 有7种数据类型:

6个基本数据类型 : string number boolean null undefined symbol

1个引用类型 : obj (你需要知道前6个基本数据类型是存储在栈中的, 1个引用类型obj存储是的引用,它的值存储在堆中的.)

对象分成3类: 普通对象 、数组对象 、函数对象。

思考问题1: 我们都知道array function都属于object,那么既然他们都是对象,一定有某些相同之处吧,对象和对象之间有什么关联呢?

如果说你没有思考过这个问题,那么可以换一个更具体的问题。

思考问题2: 打印这段代码,到浏览器控制台,你会发现我们空对象,"自带"了一个toString()?

var obj = {
    name: "ziwei",
    sex : "男",
    eat : function(){}
}
obj.toString()

问题1: array funciton obj 都是对象,那么为什么说他们都是对象,通过什么关联起来的?

问题2: 为什么一个空对象,"自带"toString()方法?

如果你不清楚以上问题的答案,恭喜你,这篇文章的主题【原型链】就可以清楚的解答你的疑惑。

原型链 什么场景下,需要原型链。

还是上面这段代码

var obj = {
    name: "ziwei",
    sex : "男",
    eat : function(){}
}
obj.toString()

如果我们想自己实现,让obj,具有toString()怎么办? 直觉肯定是添加在obj上咯。

这样因为toString(),是函数对象,所以需要在内存中开辟一块空间,存放toString()

现在,我们要声明100个obj对象,他们都需要具备toString()怎么办?

如果循环100次给每个obj都添加toString(),需要在内存空间开辟100个空间,存在100个相同的toString(),势必造成内存空间的浪费,在JS被创造时,内存还是十分宝贵的资源。

所以JS之父想出一个办法。把对象需要共享的属性和方法,放到一个内存空间里,然后每一个对象都有一个属性都指向这一个空间。

所以原型链被发明,最朴素的想法就是节省内存空间。

JS里如何设计原型链规则的呢?

1.所有对象都有的这个属性长得很奇怪,叫做 proto

var obj = {}
console.log(obj.__proto__ )  访问,你就可以查看所有object都共享的属性。

2.这个__proto__所指向的那块内存空间里的属性,并不是在var obj = {}时,才被添加进去的,而是一直都存在的。

通过 window.Object.prototype  你同样可以访问到这个共享的内存空间

3.__proto__里面还可以有__proto__,毕竟被称为原型链嘛。

之所以需要"链",你可以看这样一个例子

var arr = []
数组作为一个数组是有push()方法的, 可是我们查看 window.Object.prototype里并没有共享push方法

我们为了实现数组有push方法,但是不能让所有的对象都有push方法,为了实现这个需求,JS是这样设计的。

JS另外开辟了一个内存空间,用来专门存储数组的共有方法和属性。你可以用过window.Array.prototype来访问它

这样JS数组,arr通过__proto__继承了Array.prototype的方法,有通过Array.prototype.__proto__继承了Object.prototype上的访问。

类似的我们访问obj.name时,JS会在obj内部寻找name属性,如果没有,就会到__proto__中去寻找name,一直到Object.prototype如果还是没有name,就会返回undefined

所以这种依靠原型来继承的方式,很想一个链条,一层一层的向上寻找,所以叫做原型链,原型链的顶端就是Object.prototype

最后回答文章最初的2个问题:

问题1: array funciton obj 都是对象,那么为什么说他们都是对象,通过什么关联起来的?

他们就是通过__proto__关联的。
Array.prototype.__proto__ 继承了 Object.prototype
Function.prototype.__proto__ 继承了 Object.prototype

他们同根同源,都继承自Object.prototype,数组只是比普通的对象多了一些方法,所以他们都是对象呗

![图片上传中...]

问题2: 为什么一个空对象,"自带"toString()方法?

因为所有对象都自带__proto__属性,这个属性指向Object.prototype这个内存空间。

因为Object.prototype存储着有toString(),所以所有对象都有。

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

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

相关文章

  • 【译】每个JavaScript 开发者应该了解10个面试题

    摘要:避免脆弱的基类问题。红牌警告没有提到上述任何问题。单向数据流意味着模型是单一的事实来源。单向数据流是确定性的,而双向绑定可能导致更难以遵循和理解的副作用。原文地址 1. 你能说出两种对 JavaScript 应用开发者而言的编程范式吗? 希望听到: 2. 什么是函数编程? 希望听到: 3. 类继承和原型继承的不同? 希望听到 4. 函数式编程和面向对象编程的优缺点? ...

    mykurisu 评论0 收藏0
  • JS原型

    摘要:指向原型对象的构造函数二原型链什么是原型链原型链就是实例对象和原型对象之间的关系,他们使用来关联。改变指向实现继承创建类创建原型对象每天坚持锻炼创建构造函数函数就是改变执行代码片段中指向。 一. JS原型的简单理解 1.1 prototype prototype:是一个函数的属性,每个函数中都会有一个prototype属性,这个属性是一个指针,指向一个对象。在JavaScript...

    winterdawn 评论0 收藏0
  • JS原型

    摘要:指向原型对象的构造函数二原型链什么是原型链原型链就是实例对象和原型对象之间的关系,他们使用来关联。改变指向实现继承创建类创建原型对象每天坚持锻炼创建构造函数函数就是改变执行代码片段中指向。 一. JS原型的简单理解 1.1 prototype prototype:是一个函数的属性,每个函数中都会有一个prototype属性,这个属性是一个指针,指向一个对象。在JavaScript...

    wwolf 评论0 收藏0
  • JS原型

    摘要:指向原型对象的构造函数二原型链什么是原型链原型链就是实例对象和原型对象之间的关系,他们使用来关联。改变指向实现继承创建类创建原型对象每天坚持锻炼创建构造函数函数就是改变执行代码片段中指向。 一. JS原型的简单理解 1.1 prototype prototype:是一个函数的属性,每个函数中都会有一个prototype属性,这个属性是一个指针,指向一个对象。在JavaScript...

    Bryan 评论0 收藏0

发表评论

0条评论

Jochen

|高级讲师

TA的文章

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