javascript的prototype原理理解

时间:2024-10-12 22:06:07

prototype是函数的内置属性,每一个function都拥有这样一个属性,在js的面向对象编程上,prototype发挥着强大的作用。

某天,春哥问我你知道prototype的原理吗?我突然懵了,这个东西都知道干嘛用,怎么用,但是它的原理,确实不知道。为什么放在prototype里的方法不会在每次new对象的时候在这些对象分配资源来存放这些方法,却又可以直接调用这些方法呢?

先来看看使用new关键字生成对象的时候,javascript解释器做了些什么?

以 var obj = new FF(); 为例:

1,先创建一个空对象

2,把this指向这个空的对象

3,把对象的内置属性 _proto_ 指向FF的prototype属性(这时候对象的_proto_属性和这个构造函数的prototype属性,都指向了同一个对象)

4,通过this把属性和方法加在这个空对象上

5,return this指向的对象

如何验证上面所述呢?

 function DemoA(){
this.title = "this is a demo constructor";
this.f1 = function(){}
} function DemoB(){
this.title = "this is b demo constructor";
this.f2 = function(){}
}
DemoB.prototype = new DemoA(); var bDemo = new DemoB();
console.log(bDemo);

在控制台看到的结果是:

javascript的prototype原理理解

  从控制台的log可以看出,bDemo对象有个_proto_属性,它指向的是一个DemoA对象(代码中DemoB.prototype = new DemoA();),这个DemoA对象的_proto_属性指向函数DemoA的prototype(函数的默认prototype指向什么对象呢?console.log(DemoA.prototype);在控制台里打出的是DemoA{},众所周知函数本身就是一个对象,所有这里是不是涉及到了function更深层的原理呢?暂时先不去深究了),DemoA函数的prototype指向的是一个对象,它的_proto_属性指向了Object。

  那么现在也就知道了,用new构造器生成的对象,它的_proto_属性指向构造器的prototype属性所指向的对象,所有同一个构造器new出来的对象,是公用prototype里的方法和属性的。那么为什么可以像是直接调用对象的属性那样去调用prototype里的方法和属性呢?

  当我们对一个对象调用其方法时,js运行环境首先看,这个对象本身有没有这个方法,如果有就直接调用,如果没就查找这个对象的_proto_属性指向的对象(也就是该对象的构造器的prototype属性), 如果有该方法就调用,没有继续查找_proto_属性指向对象的_proto_属性指向的对象, 以此类推。这就是所谓原型链,在原型链的最末端,就是Object构造函数的prototype属性指向的那一个原型对象,这个原型上定义了一些基本的方法,如valueOf,toString等,这就像是java中的Object。

javascript的prototype原理理解