专栏首页前端一会JS原型链温故

JS原型链温故

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

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

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

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

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

 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}的本质行为是:

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

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原型。

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__这种链向上找,这就是原型链。

本文分享自微信公众号 - 前端小二(frontendxiao2),作者:小二君

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-12-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • javascript设计模式五:原型模式

    在javascript语言中,原型与原型链是一个非常重要的概念,因为它们是javascript语言得以成立的根本。因为javascript是基于原型的面向对象编...

    前端_AWhile
  • 《JavaScript函数式编程》的读后总结二:this指向

    解释:等同于window.a(),而this指向的是在函数执行时最终调用它的那个对象,在本例中就是window调用的,而window对象中又没有userName...

    前端_AWhile
  • 《你不知道的JavaScript》:this 绑定规则的优先级

    前面两篇讲了this的调用位置影响和绑定规则,在一般情况下想要弄清this的指向,只需找到函数的调用位置和并判断应当应用哪条绑定规则即可。但有时会出现某个调用位...

    前端_AWhile
  • JavaScript 原型中的哲学思想

    记得当年初试前端的时候,学习JavaScript过程中,原型问题一直让我疑惑许久,那时候捧着那本著名的红皮书,看到有关原型的讲解时,总是心存疑虑。

    疯狂的技术宅
  • 「思维导图学前端 」一文搞懂Javascript对象,原型,继承

    去年开始我给自己画了一张知识体系的思维导图,用于规划自己的学习范围和方向。但是我犯了一个大错,我的思维导图只是一个全局的蓝图,而在学习某个知识点的时候没有系统化...

    Tusi
  • 图解JavaScript对象原型与原型链

    原文链接:http://www.shuaihuajun.com/article/javascript-prototype-chain/

    陈帅华
  • JS 原型模式

    原型模式(Prototype pattern),用原型实例指向创建对象的类,使用于创建新的对象的类的共享原型的属性与方法。

    前端下午茶
  • ENOENT: no such file or directory, access '/usr/local/lib/node_modules/vue-cli/node_modules/get-s...

    honey缘木鱼
  • Java 程序优化之对象池

    如果一个类被频繁请求使用,那么不必每次都生成一个实例,可以将这个类都一些实例保存到一个“池”中,待需要使用的时候直接从“池”中获取。这个“池”就被称为对象池,它...

    万能青年
  • javascript大法好,不用记

    数组的操作 ---- Array.prototype.toString ( ) 把数组转变为字符串,返回字符串,arr.toString(); ---- Arr...

    前朝楚水

扫码关注云+社区

领取腾讯云代金券