function new this是构成一个javascript类的有效元素;
一个function我们可以既把它认为是函数,也可以把它认为是类,当然两者皆可有之。
我们把函数里只有this作用的语句部分称为”构造函数“部分,
而把其他部分称为"普通函数"部分。
例如:
function ClassA(xx)
{
alert("func");
ClassA.y=9;
ClassA.god=function(){alert(this.y)};
this.x=xx;
this.doit=function(){alert('hello');}
this.z="z";
}
ClassA.prototype.color="red";
ClassA.prototype.sayColor = function()
{
alert(this.color);
}
这里前3个可以认为是函数里的语句(普通函数部分);
后3个则可以认为是类中的语句(构造函数部分);
当你打算要使用类的时候,请使用new关键字,如
var a = new ClassA(3);
我们测试一下a对象里到底有些什么
for(var p in a)
alert(p + " : " + a[p]);
输出sayColor,color,x,doit,z[这里还要注意顺序,原生函数是相反的,构造函数是顺序的]
而我们调用a.god()或者a.y则会提示不存在该方法或属性。
由此可见,结论一:当new一个对象时,我们只能获得这个对象的构造函数部分以及原生函数部分
而且由之前我们做过的试验可知,
构造函数是优先于原生函数的,即可以复写,原生函数是处于系统查询属性和方法的末端。
那么前3个有何用呢?
我们可以把它们当作普通的函数来用。
比方我们直接调用ClassA();//可以不加参数,那么就输出func
当然我们var b = new ClassA(10)的时候,既输出了func,也生成了b对象,可以认为是兼具普通函数和构造函数作用。
我们继续调用ClassA.god();
发现什么了?竟然不支持!同样的ClassA.y也是访问不到的。
结论二:函数里设置自己(把自己看为对象)的属性和方法,在相应代码没有执行前,调用是无效的,但在构造函数之外是有效的,因为相应的代码已经执行过了。
例如
function ClassA(xx)
{
alert("func");
this.x=xx;
this.doit=function(){alert('hello');}
this.z="z";
}
ClassA.y=9;
ClassA.god=function(){alert(this.y)};
ClassA.god();//输出9
那么在函数体内设置自己的属性或者方法有何用呢?
我们看下面的代码:
function ClassA(xx)
{
alert("func");
ClassA.x=9;
this.x=xx;
if(ClassA._yet==undefined)
{
alert("yet");
ClassA.prototype.doit=function(){alert(this.x);}
ClassA._yet=true;
}
this.z="z";
}
ClassA.god=function(){alert(this.x);};
var a =new ClassA(2);
ClassA.god();
alert(ClassA._yet);
var b = new ClassA(5);
a.doit();
b.doit();
有几个现象:
1、是ClassA.god();ClassA._yet竟然有效了!(原先是因为在ClassA还没执行时,god()里访问不到x属性)原因就在于我们之前new 了一个ClassA,这样就执行了一遍函数代码,从而ClassA.god();就有效了,试着把ClassA.god()放到var a =new ClassA(2);之前,就和之前的结论一样了。
2、利用ClassA对象的属性或函数执行一遍就开始有效的特性,我们可以对ClassA的原生对象进行添加方法和类,默认原生对象是Object对象,原生对象的更改具有“极迟绑定”的特效,即一更改就能影响以后的代码!
所以我们在new第一ClassA中,给ClassA的原生对象添加了doit()的函数,这样以后任何ClassA实例就有doit()函数了。这样做有个好处,就是doit方法(其实是一个属性,指向函数块的指针)只要指向一个函数块,而不用每次new 的时候都重新设置指针,无疑提高了效率。这就是用“动态原形方法”创建对象。
我们继续测试,令var c = ClassA(2);
for(var p in c)
alert(p + " : " + c[p]);
发现c其实是执行函数ClassA(2)之后返回的结果,这里显然没有返回值,即undefined.
结论三:当直接使用函数名时,表示调用函数,把结果赋值,而使用new关键字时,一方面它执行了函数体内的普通函数部分,
另一方面还执行了构造函数部分,声称了一个新的对象,此时我们可以说我们执行了function的类功能。
由此可以得出本文的结论:
当我们要声明类的时候,请使用构造函数和new关键字;
当我们要执行一般函数时,构造函数部分是多余的;
在一个函数体内设置自己的属性可以实现动态原形创建类。
浙公网安备 33010602011771号