Javascript原型链的个人理解

 在工作中越来越感觉到js这门语言的重要性,无论是在前端还是node端。之前也学过一点js,但好久不去复习忘的也就差不多了。说到js,其最让人迷惑的就是其原型链继承的理解了,今天重新翻了翻相关资料,有了一点自己的理解,在这里稍微总结下:

js原型链

出自:https://www.cnblogs.com/xfcao/p/10029731.html

  在传统面向对象语言如Java,C++等中,类和对象,继承这些概念都是非常清楚的,类就是一个模版,对象就是模版生成出来的实例,继承则是指一个模版从另一个模版派生出来。Java中的反射虽然把类class也作为对象处理,但在绝大部分场合,类都是一个模版的概念。

  在C++中,函数地位特殊,能用函数指针引用,java中则有方法,方法的存在必须依赖于对象(实例方法)或者类(静态方法)的存在。

  而来到js的世界之后一切都变成了对象,对象是这个世界的唯一公民,连函数和模版都不例外,但尴尬的是js中并没有类class这个概念(ts等扩展除外)。

既然没有class,那这些对象都是怎么出来的呢?继承复用这些这么重要的概念在js中又是怎么实现的呢?

  为了更好地理解,我把js中的这些概念和传统面向对象的一些概念做个映射,这样应该能好理解的多:

  首先,js中的每一个函数都可以看成传统面向对象中的构造函数constructor。有构造函数那就肯定离不开类class,函数对象所指向的prototype就可以理解成这个constructor所归属的类。

即上图中的Foo.prototype对象。这个对象可以是任何js对象,而这个对象的属性则可以看成是类的静态属性。在new f()生成对象时,相当于运行了下面三行代码:

var obj  = {};
obj.__proto__ = f.prototype;
f(obj);
  

  其中obj的__proto__属性指向的就是其构造函数的prototype对象,也就是上文所指的constructor所关联的类。 

  其实可以这么认为,js中的任意对象都可以成为一个类class,也就是模版。通过把一个函数与对象进行绑定f.prototype=object, 这个f函数就成为了继承object的对象。

  例如:

 var a={}

a.att=10

function f(){}

f.prototype=a

b=new f()

c=new f()
console.log(b.att) //10
console.log(c.att) //10
b.__proto__.att=20
console.log(c.att) //20

运行这样的代码之后,f和a的组合就可以认为是一个完整的class,a里面存在的属性就被b,c 两个对象访问到了,同时b.__proto__ == f.prototype, 对象所指向的原型等于构造函数所指向的原型对象。

修改b的__proto__值同样将影响c.att 。这里的f.prototype就相当于一个父类,其属性相当于父类的静态属性。

 

  以上只是个人对原型链的一点见解,更详细的解析需要参考其他文献,这里不想深入。

  最后我想告诉自己的一点就是:在js中, 对象+函数(构造函数) = 类

  

 

posted @ 2020-04-24 20:10  J1ac  阅读(156)  评论(0编辑  收藏  举报