每个函数创建时默认带有一个prototype属性,其中包含一个constructor属性,和一个指向Object对象的隐藏属性__proto__。constructor属性的值为该函数的对象。在一个函数前面加上new来调用,则会创建一个隐藏连接到该函数prototype成员的新对象(由__proto__属性来链接),同时函数的this将会被绑定到那个新对象上。 函数总是返回一个值;如果没有指定返回值,就返回undefined;如果当做构造函数来调用,且返回值不是对象,则返回this(该新对象);如果返回值是对象,则它作为构造函数是没有意义的! [javascript] 复制代码 代码如下: function A(){ this.p = "haha"; return {p:"heihei"}; } var a = new A(); function A(){ this.p = "haha"; return {p:"heihei"}; } var a = new A(); alert(a.p);//显示"heihei",与var a = A();的效果一样
调用方法的时候稍微有一点绕。在JavaScript的语法中,数字后面直接跟点号,然后跟方法调用的语法是错误的;也就是说,3.negative()这样写是不对的。要想调用数值类型的方法,需要在数字后面加n个空格(n>=1),或者使用小括号将数字括起来,将其强制转化为表达式,然后再调用方法,或者干脆定义一个数值变量,也可以直接调用方法。也就是说,下面的写法都是正确的: [javascript] (3).negative(); 3 .negative(); var n = 3; n.negative(); 3["negative"](); (3).negative(); 3 .negative(); var n = 3; n.negative(); 3["negative"](); 当使用函数表达式方法定义函数时,function后面的函数名可以用来递归地调用自己,并且这个名字不会被覆盖!我们来看下面的例子, [javascript] 复制代码 代码如下: function a(n){ if(n>1) return a(n-1)+1; else return 1; }; function a(n){ if(n>1) return a(n-1)+1; else return 1; };
上述代码定义了一个函数a,并且其内部递归对自身进行了调用;现在我们用一个新的引用aa指向函数a,然后将原来的a改变,比如变为一个整数1,然后调用函数aa,如下面代码所示: [javascript] 复制代码 代码如下: var aa = a; a = 1; aa(3); var aa = a; a = 1; aa(3);
则控制台报错:TypeError: Property "a" of object [object Window] is not a function;很显然,原来的递归函数已经被破坏了。关于这个问题,我们可以在函数a的内部,用arguments.callee.caller来代替a,或者用一个函数表达式来定义函数: [javascript] 复制代码 代码如下: var b = function a(n){ if(n>1) return a(n-1)+1; else return 1; }; var bb = b; a = 3; bb(3); var b = function a(n){ if(n>1) return a(n-1)+1; else return 1; }; var bb = b; a = 3; bb(3);
此时,bb函数能正确返回我们想要的结果。 为了提高JavaScript函数的封装性,我们可以定义函数化的构造器,下面是一个例子: 复制代码 代码如下: [javascript] var funcCons = function(spec){ var that = {}; that.getName = function(){ return spec.name; }; that.says = function(){ return spec.saying || ""; }; return that; }; var myFunc = funcCons({name:"NearEast"}); var funcCons = function(spec){ var that = {}; that.getName = function(){ return spec.name; }; that.says = function(){ return spec.saying || ""; }; return that; }; var myFunc = funcCons({name:"NearEast"});