js 原型继承
最近从小了解了下关于js原型的一些知识,对js原型和继承有了新的认识。下面说一下我个人的理解(有不同理解的可以一起探讨一下)。
在js中有两种对象,函数对象和普通对象。由Function 创建的对象是函数对象,由Object 创建的对象是普通对象(这里Function和Object都是js的内置函数)。
在说原型之前我先来说一下函数对象和普通对象创建的过程:
函数对象创建的过程:
当我们用function定义一个函数的时候,这个函数会有一个属性叫做prototype,这个prototype中包含一个叫做constructor的属性指向我们定义的函数。

普通对象创建的过程:
可能有些刚接触js的小伙伴对于js中创建对象中是否要用new搞不清楚,就比如new Date() 和直接用Date()的结果是一样的。其实在new Date()是创建了一个Date的实例,而Date()仅仅是调用了Date这个方法,方法的返回值只是一个时间的字符串而已。在我们去调用new去创建一个实例的时候,实际上做了3个操作,
假设 var a=new A();
这里的new A() 可以分解为下面3步
1.var obj={};
2.obj.proto= A.prototype;
3.A.call(obj);
js原型及继承
在除了IE11以下的浏览器中都支持__proto__属性,__proto__可以理解是浏览器js编译器给我们提供的一种语法糖,在__proto__中的属性和方法都可以直接在对象中调用。

从上图中你是否有了点头绪了,为什么第二步中要将obj.__proto__指向A.prototype。实际上__proto__就相当于一跟网线,而prototype就相当于一台主机,这个主机中存放着想要被共享的内容。在默认情况下通过构造函数生成的新对象的__proto__都指向这个构造函数的这个prototype属性,这也就是为什么“实例A”.constructor=“构造函数A”.prototype.constructor(因为‘实例A’.proto=“构造函数A”.prototype,所以“实例A”.constructor===“构造函数A”.prototype.constructor, 但是这里"实例A"是不等于“构造函数A”.prototype的, 之所以“实例A”可以直接点出constructor是因为前面提及的编译器提供的一种语法糖)。经过前两步后我们新创建的obj对象就已经将父类想让他继承的东西继承下来了,可是,构造函数本身的属性些呢?
第三步就是为了解决这个问题。 在js中this的默认是指向直接调用它的对象,(在es6中的箭头函数中this指向它创建时所在的普通对象)。第3步中的call函数的作用就是强制将obj作为A的this。这样obj就拥有了A的属性了。

总结
其实原型prototype我们可以把它当作就是函数对象的一个普通属性,它的目的就是为了共享一些属性和方法给它生成的对象,所有的对象的__proto__都指向构造函的这个prototype,可以节约许多的空间。

浙公网安备 33010602011771号