Javascript中可以使用new操作符来创建一个对象,那么系统是如何使用new操作符来创建对象的呢?我们来看下流程:
- 首先需要定义一个类;
- 使用new操作符紧跟你所定义的函数来创建一个新的类的实例;
- 一旦Javascript编译器碰到了new操作符,它就创建了一个空的实例变量,将类中prototype的所有属性和方法复制到这个实例中,并将成员函数中所有的this指向这个新创建的实例;
- 接下来,执行紧跟在new操作符后面的那个函数;
- 当你执行完这个函数时,如果你试图对一个不存在的属性进行赋值,Javascript编译器将自动为你在这个范围内新创建这个属性;
- 函数执行完毕后,将这个初始化完成的实例返回.
也就说:
JavaScript实际上在使用new时,执行了下列三个过程:
- 创建空对象;
- 将类的prototype中的属性和方法复制到实例中;
- 将第一步创建的空对象做为类的参数调用类的构造函数.
例1:模拟new
描述:创建一个类person,然后创建两个变量p1和p,比较两个变量最终生成的结果.
<script type="text/javascript"> function person(name,age){ this.name=name; this.age=age; } person.prototype={ ShowName:function(){ alert(this.name); }, ShowAge:function(){ alert(this.age); } } var p1= new person("ss",20); var p = {}; for(var v in person.prototype){ p[v]=person.prototype[v]; } person.call(p,"www",'29'); p.ShowName(); </script>
创建变量p的过程虽然没有使用new,但是和p1是一样的.见下图:
例2:重载
描述:定义类person.person类构造函数中有个ShowName方法,person.prototype上有个ShowName方法.实例究竟调用的是哪个方法呢?
答:调用的person类内部的ShowName方法.
定义类person如下:
function person(name,age){ this.name=name; this.age=age; this.ShowName=function(){ alert("这是构造函数中的ShowName:"+this.name); } } person.prototype={ ShowName:function(){ alert("这是Prototype中的ShowName:"+this.name); }, ShowAge:function(){ alert(this.age); } }
实例化过程:
var p = {}; for(var v in person.prototype){ p[v]=person.prototype[v]; } //执行完for语句,p已经具备了ShowName方法.可取消下述注释,测试结果 //执行输出: // 这是Prototype中的ShowName:undefined //p.ShowName(); //因为person函数中存在下列代码: // this.ShowName={} //所以执行完此函数后 //变量p的ShowName变量被重新指向新的函数.原来的指向无处可寻 person.call(p,"www",29); //输出: // 这是这是构造函数中的ShowName:www p.ShowName();