JavaScript也有面对对象,面的对象很重要的一点就是继承,语言精粹中的继承篇章写的复杂难懂,且有些东西和现在的es6相比太过于老了,读完后这里我自己整理了一下JavaScript的继承,也对语言精粹的继承进行解释简化
这里我先上一张图直观地表示一下原型链
JavaScript中的继承和其他语言不太一样,他是原型链继承,其中的继承并不像是父子关系,而更像是师徒关系,血缘并没有那么重要,只要我认你为师傅,我就可以从你那里继承东西
怎么说呢,我可以先创建一个对象,然后去拜师
var a={ action:'a'};
var b={};
b.__proto__=a;
这里 b是先创建的,然后拜a为师,即从a处继承
所有的对象都有一个__proto__属性,表示他的原型,如果创建的时候未指定原型,则默认原型为object,所有的对象,顺着原型一直往上推,他们的原型都是object,也就是说object在原型链的顶端,是所有对象的‘祖师爷’,这时有个问题,object的原型是什么?
object的原型是null,也就是空,这是JavaScript语言的特点
当然语言精粹中并没有介绍这些,语言精粹介绍的是通过函数来创建对象,这样更好封装,但是通过上面这样讲原型链一下就理解了
在讲解语言精粹之前,要先了解几个知识点
beget() 一个创建对象的方法,传入的参数为指定该函数的原型
constructor 对象的构造函数,创建对象的时候自动调用
prototype 所有的函数都有一个这个属性,他指向函数的原型对象
当我们new一个函数创建对象时,会执行以下操作
b=new a();
- new 执行时
1. 新建一个空对象
2. 再把函数运行一遍,将 this 指向生成的对象
2. 将对象返回
函数a作为了对象b的构造函数,即b.constructor=a
同时 b.__proto__=a.prototype,这时你会发现,b.__proto__=b.constructor.prototype
这样你再去看语言精粹中写的那几个函数其实就是为了揭示这一层关系,反过来理解的话就好理解了,其实语言精粹写的太复杂反而不太好懂,看到这里,你可以再去看开头的图,就会发现一目了然
语言精粹后面的部分讲到的是封装思想,这里用到了上一章闭包的知识,当然语言精粹的作者用的处理方法非常秒
function a(){
var name='a';
var c={};
function getname(){
return name;
}
c.getname=getname;
return c;
}
b=a();
我们创建了一个b对象,然而b没办法直接访问a的内容,因为他返回是一个c对象,用c的方法访问a的内容,而a对象中的变量因为闭包的原因不会被回收,且完全不可见