前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JS原型链温故

JS原型链温故

作者头像
前端_AWhile
发布2019-08-29 13:15:18
1.2K0
发布2019-08-29 13:15:18
举报
文章被收录于专栏:前端一会前端一会

在js中,对于对象的理解很重要。

js的数据类型主要分为基本类型和引用类型。基本类型包括StringNumberBooleanundefinednull。引用类型包括Object

通常判断一个数据类型是基本类型可以使用typeof,判断一个数据类型是引用类型的可以使用instanceof

本文要讲的其实就是基于引用类型对象来说的。所谓的对象其实可以理解为若干属性的集合。狭义的对象object是对象,Function也是对象,Array同样也是对象。

object对象可以自由添加属性和方法是众所周知的,那么FunctionArray可以使用同样的方法添加属性和方法么?

代码语言:javascript
复制
 1var fn = function(){
 2    console.log(100);
 3}
 4fn.a = 20;      //函数fn添加属性a
 5fn.b = function(){      //函数fn添加方法b
 6    console.log('aaa');
 7}
 8fn.c = {        //函数fn添加属性c, c的值是个对象
 9    a: 29
10}
11console.log(fn);
12console.log(fn.a);
13console.log(fn.b());
14console.log(fn.c);
15
16//打印
17/*
18ƒ (){
19    console.log(100);
20}
21b1.html:25 20
22b1.html:19 aaa
23b1.html:26 undefined
24b1.html:27 {a: 29}
25*/

上例就是函数添加属性和方法。至于向数组添加属性和方法,在实际工作中数组的方法使用的应该不少了吧,比如concatslice之类的,所以结论是只要是对象,js中都可以自由添加属性和方法。

现在我们明确知道,函数就是对象的一种。但函数和对象其实有种鸡生蛋蛋生鸡的感觉。因为对象的创建var obj = {a:1}的本质行为是:

代码语言:javascript
复制
1var obj = new Object();
2obj.a = 1;
3
4var arr = new Array();
5arr[0] = 10
6
7console.log(typeof Object); //function
8console.log(typeof Array); //function

可以很明确的看到,狭义对象或数组本质上都是通过函数来创建出来的。此时我又要祭出我珍藏已久的JS万物图了,相信筒子们可以图中理解Function和Object之间的互相关系了。

其实函数本身就是有属性的,无需通过上文举例来证明函数可以添加属性,这个函数的已有属性就是prototype

代码语言:javascript
复制
1var Fn = function(){};  //定义构造函数Fn
2Fn.prototype.getStatus = function(){};   //在构造函数Fn的原型上添加getStatus方法
3var fn = new Fn();  //通过构造函数Fn进行new出来一个实例对象fn,
4
5//fn的原型链指向Fn的原型
6//即:fn.__proto__ === Fn.prototype

每个函数function都有一个原型属性,即prototype。每个对象都有一个隐式原型链,即__proto__,对象的__proto__指向该对象构造器的prototype原型。

代码语言:javascript
复制
1var obj = new Object();
2console.log(obj.__proto__ === Object.prototype);    //true

上例可以用一个图来表示:

这里有一个问题,js中所有对象其实最终都指向Object.prototype,那么这个Object.prototype又指向哪里呢?指向null看图:

所以结合上面几个图,可以形成这样一个结论:

在JS世界中,null为开始,由null开始衍生出Object.prototypeObject.prototype的隐式原型链指向null。正向来说Object.prototype是构造函数Function Object()的原型prototype,反过来说Object.prototype的构造器constructor也是构造函数Function Object()。这里Object.prototypeFunction Object()的关系比较容易混淆,但请认真记住。

下面给出完整原型图:

从上图可以看出一个关系,那就是js中的各对象间都是通过原型链来互相连接起来的,这个原型链将所有对象链接在了一起,这就是为什么说JS是基于原型的面向对象编程语言,即使现在有es6 7有了class类,它本质上也是基于原型链形成的语法糖而已。

js中实现的继承就是通过这条原型链来工作的:在访问一个对象的某个属性时,先该对象的现有属性中查找,如果没有,再沿着__proto__这种链向上找,这就是原型链。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-12-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端小二 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档