函数及作用域总结介绍,javascript函数及作用域的

嵌套的函数(效率域链)
当你举办函数的嵌套时,要稳重实际上功用域链是发生变化的,那点或许看起来不太直观。你可把下部的代码置入firebug监视值的变迁。

**本文结合基本javascript的高贵书籍中的内容,依据自身的知情,通过相关示例向大家来得了函数的宣示,参数,调用,闭包等片段内容,希望大家能够欣赏,如有不足,也愿意建议提出,大家共同升高。**

在js中接纳函数注意三点: 1、函数被调用时,它是运营在他被声称时的语法景况中的;

复制代码 代码如下:

在js中运用函数注意三点:
1、函数被调用时,它是运作在他被声称时的语法情状中的;

2、函数自个儿无法运行,它连接被对象调用的,函数运转时,函数体内的this指针指向调用该函数的指标,假诺调用函数时从没分明钦定该目的, this 暗中同意指向 window ( strict 情势除却,本文不涉及 strict 格局);

var testvar = 'window属性';
var o1 = {testvar:'1', fun:function(){alert('o1: ' this.testvar '<<');}};
var o2 = {testvar:'2', fun:function(){alert('o2: ' this.testvar);}};
o1.fun();'1'
o2.fun();'2'
o1.fun.call(o2);'2'

2、函数本人没辙运营,它连接被对象调用的,函数运转时,函数体内的this指针指向调用该函数的靶子,假设调用函数时不曾明确性钦赐该指标, this 暗中同意指向 window ( strict 情势除此之外,本文不涉及 strict 形式);

3、函数是一种含有可进行代码的靶子类型数据。

那是本文的第一个例证。

3、函数是一种含有可进行代码的靶子类型数据。

一、注脚函数

复制代码 代码如下:

一、注脚函数

1、使用 function 关键字

代码如下:

function myfun(a,b){ //注脚名字为myfun的函数

return a b;

}

2、 注解无名函数

function(a,b){ return a b;}佚名函数本人是无可奈何保存的,由于在js中等高校函授数是一种对象型数码,由此能够把佚名函数赋给变量来保存。

var myfun = function(a,b){ return a b;}

3、使用函数构造器Function //注意首字母大写

Function 是js内置的一个函数,他是颇具函数对象的构造器。(其他数据对象也许有和好的松手构造函数,比方Number,Object等,那些构造函数自个儿的构造器正是Function,因为她们都以函数)。

var myfun = new Function('a,b','return a b;'); 在这之中最终三个参数是函数体,后边的参数都是函数的情势参数名,个数不定,因为急需用字符串传参来组织,函数较长时这种写法很不方便人民群众,一般比相当少用,或然你会 用它来组织特定的再次回到值进而替代 eval函数。

需求留意的是,全局变量和大局函数都能够作为window对象的习性,假如存在同名的函数和变量,只可以有三个卓有成效(实际上唯有叁特性质),试试上边包车型地铁代码。

function a(){ alert('a');}

alert(window.a);  //访谈window对象的性格也得以节约window不写

var a=1;

alert(window.a);

函数和变量的扬言都产生在代码剖判期,分化的是,变量在深入分析期只声明不赋值,由此,同一个功效域内设有同名的函数和变量时,在代码运维期实践到变量赋值以前,同名函数生效,同名变量赋值之后(用新的多寡覆盖了该window对象属性原有的值),变量生效(不过要留神,在firefox 下, 在 with 伪闭包内注解的函数,只可以在申明之后工夫被调用,即,firefox 的 with 内未有对函数预先注解)。

代码如下:

with({}){
 a();  //在 firefox 下 a 是未注解
 function a(){ console.log("function a is called");}
}

只要同名称的函数被一再扬言,前面注明的将遮掩后面证明的,如:

代码如下:

alert(func1);//弹出func1(){alert(2);}

func1(){

alert(1);

}

alert(func1);  //弹出func1(){alert(2);}

func1(){  //那是终极贰回注解的func1,以该函数为准

alert(2);

}

alert(func1);  //弹出func1(){alert(2);}

var func1 = function(){  //注意 ,这里是变量赋值,不是函数注解

alert(3);

}

alert(func1);  //弹出function(){alert(3);}

除却 IE8 及IE8以下的浏览器,表明式中的函数评释都会再次回到无名氏函数,不会中标注明签订函数

代码如下:

if(function fun(){}){
   alert(fun); // error,不会大功告成注明名为 fun 的函数,但在IE8 及以下的浏览器中中会成功声惠氏个函数 fun

}

(function fun(){ });

alert(fun); //error可是尽管在 IE8 一下, 表达式中的签名函数也不能够掩饰该作用于下同名的变量:

var fun = 1; //该变量无法被函数表达式中的函数名蒙面
var f = function fun(){};
alert(f); //function fun(){};
alert(fun); //1

小心区分:

if(fun = function (){}){
   alert(fun); // ok,这里注明了二个变量,该变量保存了三个无名函数

}

js函数是援引型的靶子

var a = function(){};
var b=a;
b.x=2;
alert(a.x); //2

1、使用 function 关键字

var testvar = 'window属性';
var o3 = {
testvar:'3',
testvar2:'3**',
fun:function(){
alert('o3: ' this.testvar);//'obj3'
var inner = function(){
alert('o3-inner: ' this.testvar);//'window属性'
alert('o3-inner: ' this.testvar2);//undefined(未定义)
};
inner();
}
};
o3.fun();

二、函数的参数

js函数不会检查函数调用时传出的参数个数与定义他时的款型参数个数是不是同样,一般地,js函数调用时方可收到的参数个数为24个,当然差异的浏览器可能有距离,ECMAScript规范对那点并不曾专门的职业。

假令你不明确函数调用时传出了有一点点个参数,能够应用函数的arguments对象。

arguments 有一些像数组,被誉为伪数组,它是用来保存实参的数码,arguments.length 为流传的参数个数,arguments[0] 是第三个参数,arguments[1]是第三个参数,类推...

函数对象的length属性:那个特性相当少用到,以至很少人知情,函数的length属性便是该函数定义时的款式参数个数。

 代码如下:

function myfun(a,b){

alert(arguments.length);  //弹出调用时实际传入的参数个数

alert(arguments[0]); //对应参数a

return a b;

}

alert(myfun.length);   //形参个数,2

arguments对象还会有别的质量,举例常用的arguments.callee ,指向该函数自个儿。

要注意:借使函数内部宣称了与形参同名的子函数(同域内,变量未赋值时同名函数生效),arguments 的相应值也会被涂改,不过,在效力域内使用 var 注脚了同名的 变量则不会促成 arguments 的参数值被函数替换(但firefox 依旧替换)。

代码如下:

function aa(a , b,c){ //js 群的一道题
    function a(){}

    console.log(a); //function a
    console.log(aa);

    //如若功效域内未有 var a ,则 arguments[0] 为 function a (friefox(version 17) 则料定是function a)
    console.log(arguments[0]);
    var a = "ee";  //注销此句,考擦 arguments[0] 将变为 a 函数
    var aa = "444";
    arguments = 6;
    console.log(a);
    console.log(aa);
    console.log(arguments);
}
aa(1,2,3);

代码如下:

这里大家换了其余函数,这一个函数与原来的函数差不离相似但不一致是个中等高校函授数的写法。要小心的是中间函数运营时所在的成效域,和外界函数的效率域是不平等的。Ext可让你调用函数时钦赐函数的成效域,幸免成效域的主题素材。
变量的注解
最初化变量时必然要增加“var”关键字,未有的话那就是三个全局变量。比如,在上面包车型客车例证中,会有一个变量写在函数内部,不过你策画仅仅是声称局地的变量,但实质上也大概出现覆盖全局变量的值的事态。在FIREBUG "DOM"的标签页中,你可因此检查实验“window”看到全体的全局变量。假若你发掘有“k”或“x”变量那表达您把这一个变量分配在叁个不确切的成效域里面。见下例:

三、函数的重返值

js函数使用 return 语句再次来到值。

成套数据类型都可以看成函数的重回值(包蕴函数),js函数也得以未有再次回到值。

function myfun(a,b){ //注明名叫myfun的函数 

复制代码 代码如下:

四、函数调用

函数自身是不会运作的,当它运转时,总是存在叁个调用它的对象。

默许景况下,在别的语法情况中,若无显式钦赐函数的调用对象,就是指通过window对象来调用该函数,此时,函数体内的this指针指向window对象。

代码如下:

function myfun(a,b){

 alert(this);

return a b;

}

myfun(1,2); // 调用函数并传播2个参数,那2个参数分别对应方式参数a,b调用函数时,即使传入的参数个数超越形式参数,就唯有用arguments加下标来收取了。

出于尚未显式钦命调用函数的靶子,alert(this)将弹出 window对象。这种调用方法是最遍布的。

 

用以体现钦定函数的调用对象方法有四个:

1、若是一个函数被赋为贰个对象的属性值,那个函数只可以通过该目的来走访(但绝不是说该函数只可以被该目的调用),通过该指标调用那一个函数的方法临近以面向对象编制程序语言中的方法调用(实际上在js中也习于旧贯使用办法这种称为)。

代码如下:

var obj={}; //定义贰个指标

obj.fun=function(a,b){

alert(this); //弹出this指针

return a b;

} //对象属性值为函数

alert(obj.fun);// 访谈fun函数。 只可以通过该对象来访问那一个函数

obj.fun(1,2);  //通过obj对象来调用fun函数,将弹出obj对象。这种方法也称为调用obj对象的fun方法。

2、 大肆钦点函数的调用对象:在某些语法意况中,固然得以况兼做客到函数fun和对象obj,只要您愿意,能够内定通过obj对象来调用fun函数。钦赐方法 有2种:call方法和apply方法。(因为window对象是浏览器情状下的世界级对象,在其它语法境况中都能访谈到window对象,因而,任何函数 都足以通过window对象来调用)

代码如下:

function fun(a,b){

alert(this);

return a b;

}

var obj={};

fun.call(obj,1,2);   //通过obj对象来调用fun函数,并传播2个参数,弹出的指针为obj对象。

 

var obj2={};

obj2.fun2 = function(a,b){ //obj2对象的性格fun2是贰个函数

alert(this);

return a b;

};

obj2.fun2.call(obj,1,2);   //通过obj对象来调用obj2指标的fun2属性值所保存的函数,弹出的this指针是obj对象

//比较掩盖的不二秘籍调用:数组调用一个函数[9,function(){ alert(this[0]); }][1]();

//使用window对象调用函数上面两种办法是等价的
fun(1,2);
window.fun(1,2);  //即使fun函数是全局函数
fun.call(window,1,2);
fun.call(this,1,2);  //假如该句代码在全局境况下(或然被window对象调用的函数体内),因为该语法意况下的this就是指向window对象。
func.call(); //如若函数无需传参
func.call(null,1,2);
func.call(undefined,1,2);var name = "window";
function kkk(){
console.log(this.name); // not ie
}
kkk(); //window
kkk.call(kkk); //kkk 函数被本人调用了

另一种比较轻易忽视的荒谬是,在A 对象的方法中,实行了接纳了 B 对象的法子调用,试图在 B 对象的办法里应用 this 来访谈 A 对象,那在种种回调函数中相比较广泛,最广大的情事正是 ajax 回调函数中应用 this 。

代码如下:

var obj = {
   data:null,
   getData:function(){
          $.post(url,{param:token},function(dataBack){ //jQuery ajax post method
                 this.data = dataBack; //试图将服务器再次来到的数额赋给 obj.data ,但那边的 this 已经指向 jQuery 的 ajax 对象了
           },'json');  
   }
}

//准确做法
var obj = {
   data:null,
   getData:function(){
          var host = this; //保存 obj 对象的引用
          $.post(url,{param:"token"},function(dataBack){
                 host.data = dataBack;
           },'json');  
   }
}

3、函数作为对象构造器(构造函数)

当函数使用 new 运算作为指标构造器运转时,this 指向新布局出目标,即使该构造函数的再次来到值不是 null 以外的对象,构造函数运营实现将回到 this 指向的目的,不然重临原定义的靶子。

代码如下:

function Fun(){

this.a = 1;

this.b = 3;

console.log(this); //{a:1,b:2}

// return {a:999};  //加上此举 ,将赶回 {a:999}

 }

var obj = new Fun();  //obj = {a:1,b:2} ,若无参数,也得以写成 var obj = new Fun;

return a b;

var i = 4;
var j = 5;
var k = 7;
var fn = function(){
var i = 6;
k = 8;//注意眼下未有var 所以那句话的意思的把8赋予到变量k中去!
alert(i);//6
alert(j);//5
alert(k '-1');//8-1
x = 1;//那句的效应有二种情状,创立全体变量x或掩饰(overwrite)全体变量x
};
fn();
alert(k '-2');//8-2 (注意不是7-2)

五、函数作用域

js的变量功能域是函数级的,在js里未有临近c语言的块级成效域。

js编制程序意况的五星级作用域是window对象下的界定,称为全局成效域,全局功效域中的变量称为全局变量。

js函数内的变量不能够在函数外面访谈,在函数内却能够访问函数外的变量,函数内的变量称为局地变量。

js函数能够嵌套,七个函数的少见嵌套构成了七个成效域的偶发嵌套,这名称为js的成效域链。

js功用域链的变量访问准则是:假设当前成效域内存在要访谈的变量,则动用当前功效域的变量,不然到上一层成效域内寻觅,直到全局效率域,假设找不到,则该变量为未注脚。

注意,变量的扬言在代码深入分析期达成,假使当前成效域的变量的宣示和赋值语句写在变量访谈语句后边,js函数会感到当下效率域已经存在要拜谒的变量不再向下边功用域查找,但是,由于变量的赋值发生的代码运营期,访谈的到变量将是undefined。

代码如下:

var c=1000;

function out(){

var a=1;

var b=2;

function fun(){

 alert(a); //undefined

var a=10;

 alert(a); //10

alert(b); //2

alert(c); //1000

}

fun();

}

out();

}

与日前例子变化一点都不大,另外注意的是函数内的k前面是绝非var关键字的,所以那边不是声称局地变量,而是将有些值再度分配到k这么些全局变量中。其它要注意的是,alert方法推行时期,参数i是当前能找到的局地变量,它的值是6,但参数j在脚下成效域找不到,就本着成效域链(scope chain)向上查找,向来找到全局变量的百般j截至。
在Ext中钦命效用域
前边已提起,当调用函数时Ext能灵活管理功用域的难题。部分剧情出自dj的帖子。
调用函数时,你能够把this想象为各样函数内的三个极其(躲起来的)参数。无论怎么时候,JavaScript都会把this放到function内部。它是根据一种非常简单的研讨:假如函数间接是有个别对象的积极分子,那么this的值就是以此目的。即使函数不是有些对象的成员那么this的值便设为某种全局对象(常见有,浏览器中的window对象)。下边包车型地铁在那之中等高校函授数能够清晰的观看这种思量。
二个函数,若是分配到有些变量的,即不属于另外对象下的一员,那么this的参数就成为windows对象。上边是贰个例证,可直接粘贴到Firebug的console:

六、无名氏函数的调用

无名氏函数的选择在js十分重大,由于js中总体数据都以指标,包括函数,因而平日应用函数作为另一个函数的参数或重回值。

假定无名函数未有被保存,则运维后即被从内部存款和储蓄器中自由。

无名函数的调用方式一般是直接把佚名函数放在括号内代表函数名。如:

(function(a,b){ return a b;})(1,2); //注解并实行无名函数,运维时传出三个参数:1和2

//或者

(function(a,b){ return a b;}(1,2));

//下边这种写法是百无一用的:

function(a,b){ return a b;}(1,2); 

是因为js中语句甘休的分集团能够回顾,js引擎会以为function(a,b){ return a b;}是一句语句截至,因而佚名函数只申明了并没有被调用,若是语句未有传参(1,2)写成(),还有可能会导致错误,js中空括号是语法错误。

上面这种写法是不利的。

var  ab = function(a,b){ return a b;}(1,2);  // ab=3

js 分析语法时,若是表达式出现在赋值运算或操作符运算中,是"贪婪相称"的(尽量求值)

function(t){ return 1 t;}(); //error
var f = function(t){ return t 1;}(); // ok

~ function(t){return t 1;}();  //ok

  • function(t){return t 1;}(); //ok

假诺你只是想把一个匿名函数赋给多个变量,记得在赋值语句前边加上分号,不然,假诺后边跟了小括号就改为了函数调用了,极度是小括号与函数结尾之间相隔了多行时,这种不当往往很难开采。

实质上付出中,佚名函数恐怕以运算值的章程赶回,这种气象可能不轻易看到,举例

var a =1;
var obj = {a:2,f:function(){ return this.a;}};

(1,obj.f)(); //1 逗号表明式反悔了八个佚名函数,当以此无名函数被调用时,函数体内的 thsi 指向 window

评释并霎时运营无名函数被喻为”自实施函数“,自实行函数平常用来封装一段js代码。由于函数效率域的表征,自试行函数内的变量无法被外表访问,放在函数内 的代码不会对外边的代码产生影响,可防止止形成变量污染。js开拓很轻便导致变量污染,在开垦中时时引进其余编码人士支出的代码,假若不相同的编码人士定义 了同名称分裂含义的全局变量或函数,便导致了变量污染,同一效率域内出现同名的变量或函数,后来的将覆盖后边的。

(function(){

   //本人的代码.....

})();无名函数仍是能够使内部存款和储蓄器及时放出:因为变量被声称在无名函数内,假若那么些变量未有在无名氏函数之外被引用,那么这一个函数运营实现,里面包车型的士变量所占用的内部存款和储蓄器就能够马上释放。

函数的name:在firefox等浏览器,函数有三个name属性,就是该函数的函数名,可是那特天性在IE中不设有,别的,无名氏函数的name为空值。

var a=function(){}
alert(a.name); //undefined,a是二个存储了四个无名氏函数的变量
function b(){}
alert(b.name); //b ,but undefined for IE

2、 注明无名氏函数

复制代码 代码如下:

七、函数被调用时,运维在她被定义时的条件中

无论是函数在哪儿被调用,被什么人调用,都没办法儿改换其被声称时的语法情状,那决定了函数的运维情况。

代码如下:

var x=99;

var inerFun=null;

function fun1(){

    alert(x);

}

function holder(){

  var x = 100;

  var fun2 = fun1;

 inerFun = function(){ alert(x);}

  fun1(); //99

 fun2();//99

  inerFun(); //100

}

holder();

fun1(); //99

inerFun(); //100

 

 //另三个事例:

var x = 100;
var y=77;
var a1={
x:99,
xx:function(){
  //var y=88;  //如若注释这几个变量,y将是全局变量的77
  alert(y); //未有动用this指针,调用函数的指标无法影响y的值,函数运营时将从这里按效果与利益域链逐级找出取值
  alert(this.x);  //使用了 this 指针,调用函数的
}
}

a1.xx();
a1.xx.call(window);

var jj = a1.xx;

jj(); //效果跟a1.xx.call(window); 同样//试试上边代码

var x=99;
function xb(){
this.x=100;
this.a = (function(){return this.x}).call(this); //new 的时候试行了,佚名函数被 实例化的靶子 调用
this.b = (function(){return this.x})(); //new 的时候实行了,无名函数被window调用
this.method = function(){return this.x;}
}

var xbObj = new xb();
console.log(xbObj.x);
console.log(xbObj.a);
console.log(xbObj.b);
console.log(xbObj.method());

小心区分调用函数的对象、函数证明时的语法情况、函数调用语句的语法蒙受那多少个概念

1、调用函数的靶子(或许说函数的调用方式)决定了函数运营时函数体内的this指针指向何人。

2、函数声明时的语法景况调节了函数运营时的拜谒权限。

3、函数调用语句的语法意况调节了函数是不是真的能够被调用及曾几何时被调用(唯有函数在有个别语法蒙受是可知的,那几个函数技能被调用)。

函数在运作时,产生贰个 arguments 对象可以访谈传入函数内的参数,arguments 有三个性情能够针对函数自己:arguments.callee。

函数运营时,函数的 caller 属性能够针对本函数调用讲话所在函数,譬如,a函数在b函数体内被调用,则当a函数运转时,a.caller就指向了b函数,纵然a 函数在大局情状中被调用则 a.caller=null

arguments 和a.caller 的值与函数的每贰遍调用直接关系,他们都以在函数运营时发生的,只可以在函数体内访问。

IE8及IE8以下浏览器中,a 函数的内的 arguments.caller( IE9之后那本天性被移除) 指向 a.caller 施行时的 arguments (arguments.caller.callee === a.caller)。

 

var obj = {
    toString:function(){ return 'obj的限定内(效能域内)';}, //重写toString函数,方便实行console.log(this)时的出口
    func: function(){
        // 这里的函数直接从属与目的"object"
        console.log(this);
        var innerFunc = function(){
            //n这里的函数不是一定目的的直接成员,只是别的三个函数的变量而已
            console.log(this);
        };
        innerFunc();
    }
};
obj.func();
// 输出 "obj的限定内(成效域内)"
// 输出 "Window的局地唇齿相依内容..."

八、字符串实时分析中的函数调用:eval()、new Function()、setTimeout()、setInterval()

eval() 与 window.eval()

代码如下:

function a(){
    console.log('out of b');
}
function b(){
    function a(){ console.log("in b"); }
    var f = function(){ a(); };
    eval('a()'); // in b
    window.eval('a()'); //out of b ,ie 678 in b, ie 9 out of b
    (new Function('a();'))(); //out of b
    setTimeout('a()',1000);   // out of b
    setTimeout(f,2000);// in b
}
b();

eval() 中的代码实践于eval() 语句所处的职能域内:

代码如下:

var Objinit = function(){
  var param = 123;
  return {
          execute:function(codes){
                eval(codes);
          },
          setCallback:function(f){
               this.callback = f;
          },
          fireCallback:function(){
               this.callback && this.callback.call(this);
          },
         getParam:function(){
             return param;
         }
   }
};

var obj = Objinit ();
var param = 'outerParam';
console.log(param,obj.getParam()); //outerParam 123
obj.execute('param = 456');
console.log(param,obj.getParam()); //outerParam 456
obj.setCallback(function(){ eval("param = 8888")});
obj.fireCallback();
console.log(param,obj.getParam()); //8888 456
obj.setCallback(function(){ eval("eval(param = 9999)")});
obj.fireCallback();
console.log(param,obj.getParam()); //9999 456eval()

字符串中深入分析出的代码运在 eval 所在的效用域,window.eval() 则是运作在一级作用域(低版本 chrome 和 低于IE9 则同 eval()).

IE 中 ,window.execScript();  相当于 window.eval()

new Function()、setTimeout()、setInterval()  的率先个字符串参数所剖判获得的代码,都以在五星级成效域施行。

 

function(a,b){ return a b;}无名氏函数本身是无法保存的,由于在js中等学校函授数是一种对象型数码,由此能够把无名氏函数赋给变量来保存。

缺省下是那般调用贰个参数的-但你也足以人工地改成this参数,只是语法上有个别分裂。将最后一行的"obj.func();" 改为:

谈起底说一下IE6的内部存款和储蓄器泄漏

在IE 6 中,非原生js对象(DOM 等)的轮回引用会招致内部存款和储蓄器走漏,使用闭包时一旦涉嫌非 js 原生对象援用时要留意。

function fun(){

var node = document.getElementById('a');
node.onclick = function(){ alert(node.value); };

node = null; //打断循环引用防止内部存款和储蓄器败露

node 保存的是 DOM 对象,DOM对象存在于 fun 之外(何况平昔留存,就算去除也只是从文书档案树移出),fun 推行后发生闭包,也构成DOM对象与回调函数的大循环引用(node-function-node),在IE 6 下产生内部存款和储蓄器败露。

 

var myfun = function(a,b){ return a b;}
3、使用函数构造器Function //注意首字母大写

复制代码 代码如下:

Function 是js内置的贰个函数,他是全数函数对象的构造器。(其余数据对象也许有谐和的放置构造函数,举个例子Number,Object等,这一个构造函数自个儿的构造器正是Function,因为他们都是函数)。

obj.func.call(window);
// 输出 "Window的一些皮之不存毛将焉附内容..."
// 输出 "Window的有的连锁内容..."

var myfun = new Function('a,b','return a b;'); 其中最终一个参数是函数体,前面包车型大巴参数都以函数的格局参数名,个数不定,因为需求用字符串传参来组织,函数较长时这种写法很不便于,一般非常少用,大概你会用它来组织特定的重回值进而取代eval函数。

从地点的例证中得以窥见,call实际上是另外二个函数(方法)。call 属于系统为obj.func内建的章程(依照JavaScript之特点可查出,函数是一种对象。)。
通过这样改造this指向的功能域,我们得以三番五次用五个例子来改正innerFunc中的this参数,——“不科学”的针对性:

急需小心的是,全局变量和大局函数都得以视作window对象的质量,如若存在同名的函数和变量,只好有三个生效(实际上独有叁个属性),试试上面包车型客车代码。

复制代码 代码如下:

 代码如下:

var obj = {
    toString:function(){ return 'obj的界定内(功能域内)';}, //重写toString函数,方便实施console.log(this)时的输出
    func: function(){
        // 这里的函数直接从属与目的"object"
        console.log(this);
        var innerFunc = function(){
            //n这里的函数不是一定目的的直白成员,只是其他二个函数的变量而已
            console.log(this);
        };
        innerFunc.call(this);
    }
};
obj.func();
// 输出 "obj的限定内(成效域内)"
// 输出 "obj的限制内(功用域内)"

function a(){ alert('a');} 

Ext的成效域配置
可以观察,没有分配功效域的函数,它的this"指向的是浏览器的window对象(如事件句柄event handler等等),——除非大家转移this的指针。Ext的成都百货上千类中 scope是贰个安插项(configuration)能够进行指针的绑定。相关的事例参谋Ajax.request。
Ext的createDelegate函数
*除此之外内建的call/apply方法,Ext还为我们提供-- 帮助方法createDelegate。 该函数的基本作用是绑定this指针但不立即施行。传入贰个参数,createDelegate方法会保证函数是运作在那几个参数的效率域中。如:

alert(window.a);  //访谈window对象的质量也得以节约window不写

复制代码 代码如下:

var a=1;

var obj = {
    toString:function(){ return 'obj的限制内(效用域内)';}, //重写toString函数,方便试行console.log(this)时的出口
    func: function(){
        // 这里的函数直接从属与目的"object"
        console.log(this);
        var innerFunc = function(){
            //n这里的函数不是特定指标的从来成员,只是别的二个函数的变量而已
            console.log(this);
        };
        innerFunc = innerFunc.createDelegate(this); // 这里大家用委托的函数覆盖了原函数。
        innerFunc(); // 依据一般的写法调用函数
    }
};
obj.func();
// 输出 "obj的限制内(成效域内)"
// 输出 "obj的范围内(功效域内)"

alert(window.a);

那是三个细小的例证,其规律是不行基本基础的,希望可以优秀消化摄取。固然如此,在切切实实专业中,大家依旧轻巧认为吸引,但大概,倘诺能根据上边的理论知识去分析来因去果,万变照旧不离当中的。
别的还恐怕有一样东西,看看下边包车型客车例证:

函 数和变量的证明都发出在代码分析期,不一样的是,变量在分析期只表明不赋值,因而,同四个成效域内设有同名的函数和变量时,在代码运营期实施到变量赋值此前,同名函数生效,同名变量赋值之后(用新的数码覆盖了该window对象属性原有的值),变量生效(可是要注意,在firefox 下, 在 with 伪闭包内表明的函数,只好在证明之后技能被调用,即,firefox 的 with 内未有对函数预先表明)。

复制代码 代码如下:

代码如下:

varsDs.load({callback: function(records){
col_length = varsDs.getCount();//这里的varDs离开了效能域?
//col_length = this.getCount();//这个this等于store吗?
for (var x = 0; x < col_length; x )
{
colarray[x] = varsDs.getAt(x).get('hex');
}
}});不过能够写得更鲜明:
var obj = {
callback: function(records){
col_length = varsDs.getCount();//这里的varDs离开了作用域?
//col_length = this.getCount();//这个this等于store吗?
// ...
}
};

with({}){  a();  //在 firefox 下 a 是未注明  function a(){ console.log("function a is called");} }

varsDs.load(obj);今后函数callback间接挂在obj上,因而this指针等于obj。
唯独注意: 那样做没用的。为啥?因为你不知obj.callback最后实践时产生什么景况。试想一下Ext.data.Store的load方法(仿造的贯彻):

即便同名称的函数被一再扬言,前边表明的将掩饰前边注明的,如:

复制代码 代码如下:

 代码如下:

...
    load : function(config) {
        var o = {};
        o.callback = config.callback;
         //进行加载
        o.callback();
    }
...

alert(func1);//弹出func1(){alert(2);} 

那么些仿造的达成中,回调函数的作用域是个人变量“o”。 因为经常你不可能获悉函数是如何被调用的,要是不注解成效域,你相当的大概不只怕在回调函数中运用this参数。

func1(){

当你实行函数的嵌套时,要注意实际上效能域链是发生变化的,那一点可能看起来不太直观。你可把下部的代码置入...

alert(1);

}

alert(func1);  //弹出func1(){alert(2);}

func1(){  //那是最终一遍注解的func1,以该函数为准

alert(2);

}

alert(func1);  //弹出func1(){alert(2);}

var func1 = function(){  //注意 ,这里是变量赋值,不是函数申明

alert(3);

}

alert(func1);  //弹出function(){alert(3);}

除开 IE8 及IE8以下的浏览器,表明式中的函数注明都会回到无名氏函数,不会成功声明签署函数

代码如下:

if(function fun(){}){    alert(fun); // error,不会旗开得胜注脚名叫 fun 的函数,但在IE8 及以下的浏览器中中会成功声贝拉米(Bellamy)(Nutrilon)个函数 fun

}

(function fun(){ });

alert(fun); //error可是固然在 IE8 一下, 表明式中的具名函数也不能够掩盖该意义于下同名的变量:

var fun = 1; //该变量不能够被函数表明式中的函数名蒙面 var f = function fun(){}; alert(f); //function fun(){}; alert(fun); //1

瞩目区分:

 

if(fun = function (){}){    alert(fun); // ok,这里注解了三个变量,该变量保存了贰个佚名函数

}

js函数是引用型的靶子

var a = function(){}; var b=a; b.x=2; alert(a.x); //2

二、函数的参数

js函数不会检讨函数调用时传出的参数个数与概念他时的样式参数个数是不是一样,一般地,js函数调用时得以收到的参数个数为二十三个,当然差异的浏览器或许区别,ECMAScript规范对那或多或少并不曾正式。

假如你不明确函数调用时传出了不怎么个参数,可以运用函数的arguments对象。

arguments 有一点点像数组,arguments.length 为流传的参数个数,arguments[0] 是率先个参数,arguments[1]是第3个参数,类推...

函数对象的length属性:那性情格相当少用到,以至比相当少人精通,函数的length属性就是该函数定义时的款型参数个数。

 代码如下:

function myfun(a,b){

alert(arguments.length);  //弹出调用时实际传入的参数个数

alert(arguments[0]); //对应参数a

return a b;

}

alert(myfun.length);   //形参个数,2

arguments对象还应该有任何品质,比方常用的arguments.callee ,指向该函数自个儿。

 

要留心:假设函数内部宣称了与形参同名的子函数(同域内,变量未赋值时同名函数生效),arguments 的相应值也会被涂改,不过,在效果与利益域内使用 var 注明了同名的 变量则不会导致 arguments 的参数值被函数替换(但firefox 照旧替换)。

  代码如下:

function aa(a , b,c){ //js 群的一道题     function a(){}
    console.log(a); //function a     console.log(aa);
    //倘诺效能域内未有 var a ,则 arguments[0] 为 function a (friefox(version 17) 则终将是function a)     console.log(arguments[0]);     var a = "ee";  //注销此句,考擦 arguments[0] 将变为 a 函数     var aa = "444";     arguments = 6;     console.log(a);     console.log(aa);     console.log(arguments); } aa(1,2,3);

三、函数的再次来到值

 

js函数使用 return 语句重回值。

任何数据类型都足以视作函数的再次来到值(包括函数),js函数也能够未有重临值。

四、函数调用

函数自身是不会运作的,当它运转时,总是存在三个调用它的对象。

暗中认可意况下,在任何语法情形中,若无显式内定函数的调用对象,正是指通过window对象来调用该函数,此时,函数体内的this指针指向window对象。

 代码如下:

function myfun(a,b){

 

 alert(this);

return a b;

}

myfun(1,2); // 调用函数并传到2个参数,这2个参数分别对应情势参数a,b调用函数时,假诺传入的参数个数当先格局参数,就只有用arguments加下标来接过了。

出于并未有显式钦赐调用函数的靶子,alert(this)将弹出 window对象。这种调用方法是最普及的。

 

用于显式钦赐函数的调用对象方法有八个:

1、借使二个函数被赋为八个对象的属性值,那几个函数只可以通过该目的来拜会(但并不是是说该函数只好被该对象调用),通过该目的调用这几个函数的艺术周围以面向对象编制程序语言中的方法调用(实际上在js中也习贯使用方式这种称为)。

代码如下:

var obj={}; //定义二个对象

 

obj.fun=function(a,b){

alert(this); //弹出this指针

return a b;

} //对象属性值为函数

alert(obj.fun);// 访谈fun函数。 只好因而该对象来探望这一个函数

obj.fun(1,2);  //通过obj对象来调用fun函数,将弹出obj对象。这种办法也称为调用obj对象的fun方法。

2、 大肆内定函数的调用对象:在有个别语法景况中,假设能够何况做客到函数fun和指标obj,只要您愿意,能够内定通过obj对象来调用fun函数。钦赐方法 有2种:call方法和apply方法。(因为window对象是浏览器情状下的一级对象,在其他语法蒙受中都能访谈到window对象,因而,任何函数 都足以因此window对象来调用)

  代码如下:

function fun(a,b){

alert(this);

return a b;

}

var obj={};

fun.call(obj,1,2);   //通过obj对象来调用fun函数,并传播2个参数,弹出的指针为obj对象。

 

var obj2={};

obj2.fun2 = function(a,b){ //obj2对象的性情fun2是三个函数

alert(this);

return a b;

};

obj2.fun2.call(obj,1,2);   //通过obj对象来调用obj2对象的fun2属性值所保存的函数,弹出的this指针是obj对象

//相比隐藏的章程调用:数组调用二个函数[9,function(){ alert(this[0]); }][1]();

//使用window对象调用函数下边三种格局是等价的 fun(1,2); window.fun(1,2);  //如若fun函数是全局函数 fun.call(window,1,2); fun.call(this,1,2);  //假设该句代码在全局情况下(只怕被window对象调用的函数体内),因为该语法景况下的this正是指向window对象。 func.call(); //如若函数无需传参 func.call(null,1,2); func.call(undefined,1,2);var name = "window"; function kkk(){ console.log(this.name); // not ie } kkk(); //window kkk.call(kkk); //kkk 函数被自个儿调用了

另一种相比较易于忽视的谬误是,在A 对象的办法中,实践了选拔了 B 对象的点子调用,试图在 B 对象的主意里使用 this 来访谈 A 对象,那在种种回调函数中比较普及,最广大的场所正是 ajax 回调函数中动用 this 。

  代码如下:

var obj = {    data:null,    getData:function(){           $.post(url,{param:token},function(dataBack){ //jQuery ajax post method                  this.data = dataBack; //试图将服务器再次回到的数量赋给 obj.data ,但那边的 this 已经针对 jQuery 的 ajax 对象了            },'json');      } }

 

//正确做法 var obj = {    data:null,    getData:function(){           var host = this; //保存 obj 对象的援用           $.post(url,{param:"token"},function(dataBack){                  host.data = dataBack;            },'json');      } }

3、apply方法调用:

 

apply方法与call方法独一分化的地点是函数字传送参格局各异。

obj2.fun2.call(obj,1,2);   改为 apply格局正是obj2.fun2.apply(obj,[1,2]);

apply使用类数组格局传参,除数组外,还足以采取arguments、HTMLCollection来传参,但arguments并不是数组,如:

var obj={};

function fun_1(x,y){

   function fun_2(a,b){

     return a b;

  }

fun_2.apply(obj,arguments);  //用fun_1的arguments对象来传参,实际上是接受了x,y

}apply 传参在IE8 及IE8一下的浏览器中哟2个难题

在 call 和 apply 调用中,假使传入标量数据(true/false ,string,number),函数运维时将把她们传出的基本数据包装成靶子,然后把this指向包装后的目的,试试上面包车型大巴代码。 function a(){

alert(typeof this);

 alert(this.constructor);

 alert(this);

}

a.call(false);

a.call(100);

a.call('hello');

乃至能够用这些特性来传参数,不过不提出这种用法:

function a(){  alert(1 this); } //对象在运算中自行举办类型调换

a.call(100); //101

4、函数作为指标构造器

当函数使用 new 运算作为靶子构造器运维时,this 指向新布局出指标,假若该构造函数的再次来到值不是 null 以外的目的,构造函数运营达成将再次回到 this 指向的靶子,不然再次回到原定义的靶子。

  代码如下:

function Fun(){

this.a = 1;

this.b = 3;

console.log(this); //{a:1,b:2}

// return {a:999};  //加上此举 ,将回到 {a:999}

 }

var obj = new Fun();  //obj = {a:1,b:2} ,若无参数,也得以写成 var obj = new Fun;

五、函数成效域

 

js的变量功用域是函数级的,在js里不曾看似c语言的块级成效域。

js编制程序情形的头号功能域是window对象下的限定,称为全局效用域,全局成效域中的变量称为全局变量。

js函数内的变量不能够在函数外面访问,在函数内却得以访问函数外的变量,函数内的变量称为局地变量。

js函数能够嵌套,多个函数的少有嵌套构成了三个成效域的少有嵌套,那称为js的效率域链。

js成效域链的变量访谈法规是:即使当前功能域内部存款和储蓄器在要访谈的变量,则使用当前功效域的变量,不然到上一层效能域内搜寻,直到全局作用域,假诺找不到,则该变量为未阐明。

在意,变量的证明在代码剖判期完毕,要是当前功能域的变量的宣示和赋值语句写在变量访谈语句后边,js函数会感到近来功用域已经存在要拜见的变量不再向上级作用域查找,然则,由于变量的赋值产生的代码运转期,访问的到变量将是undefined.

如:

代码如下:

var c=1000;

 

function out(){

var a=1;

var b=2;

function fun(){

 alert(a); //undefined

var a=10;

 alert(a); //10

alert(b); //2

alert(c); //1000

}

fun();

}

out();

六、无名氏函数的调用

 

无名函数的选取在js很关键,由于js中全体数据都以目的,包罗函数,由此平常应用函数作为另三个函数的参数或重回值。

假使无名函数未有被保存,则运维后即被从内部存储器中自由。

无名函数的调用形式一般是平昔把无名氏函数放在括号内代表函数名。如:

(function(a,b){ return a b;})(1,2); //评释并实施无名氏函数,运转时传出八个参数:1和2

//或者

(function(a,b){ return a b;}(1,2));

//下边这种写法是指鹿为马的:

function(a,b){ return a b;}(1,2); 

是因为js中语句甘休的子集团能够简简单单,js引擎会以为function(a,b){ return a b;}是一句语句停止,由此无名函数只注明了未曾被调用,假诺语句未有传参(1,2)写成(),还或许会导致错误,js中空括号是语法错误。

上边这种写法是没有错的。

var  ab = function(a,b){ return a b;}(1,2);  // ab=3

js 深入分析语法时,借使表明式出现在赋值运算或操作符运算中,是"贪婪相称"的(尽量求值)

function(t){ return 1 t;}(); //error var f = function(t){ return t 1;}(); // ok

~ function(t){return t 1;}();  //ok function(t){return t 1;}(); //ok

假设你只是想把八个佚名函数赋给二个变量,记得在赋值语句前边加上分号,否则,要是后边跟了小括号就改为了函数调用了,特别是小括号与函数结尾之间相隔了多行时,这种错误往往很难开采。

其实开辟中,佚名函数也许以运算值的情势赶回,这种景况可能不易于见到,举例

var a =1; var obj = {a:2,f:function(){ return this.a;}};

(1,obj.f)(); //1 逗号表明式反悔了多个无名函数,当以此无名函数被调用时,函数体内的 thsi 指向 window

评释并及时运转佚名函数被称得上”自实施函数“,自实行函数常常用来封装一段js代码。由于函数成效域的个性,自进行函数内的变量不能被表面访谈,放在函数内 的代码不会对外部的代码暴发震慑,可避防止产生变量污染。js开垦很轻便形成变量污染,在开拓中日常引入别的编码职员支出的代码,固然区别的编码人士定义 了同名称不一致含义的全局变量或函数,便导致了变量污染,同一成效域内出现同名的变量或函数,后来的将遮掩后边的。

(function(){

   //本人的代码.....

})();无名函数还足以使内部存款和储蓄器及时放出:因为变量被声称在无名氏函数内,假使那个变量未有在佚名函数之外被引述,那么这一个函数运维实现,里面包车型客车变量所占领的内部存款和储蓄器就能够登时释放。

函数的name:在firefox等浏览器,函数有三个name属性,就是该函数的函数名,不过那一个特性在IE中不设有,别的,无名函数的name为空值。

var a=function(){} alert(a.name); //undefined,a是一个积累了贰个无名氏函数的变量 function b(){} alert(b.name); //b ,but undefined for IE

七、函数被调用时,运维在她被定义时的条件中

随便函数在哪个地方被调用,被哪个人调用,都敬敏不谢转移其被声称时的语法意况,那决定了函数的周转条件

代码如下:

var x=99;

var inerFun=null;

function fun1(){

    alert(x);

}

function holder(){

  var x = 100;

  var fun2 = fun1;

 inerFun = function(){ alert(x);}

  fun1(); //99

 fun2();//99

  inerFun(); //100

}

holder();

fun1(); //99

inerFun(); //100

 

 //另多个例证:

var x = 100; var y=77; var a1={ x:99, xx:function(){   //var y=88;  //如果注释这么些变量,y将是全局变量的77   alert(y); //未有利用this指针,调用函数的目标不或然影响y的值,函数运转时将从此处按效果与利益域链逐级搜索取值   alert(this.x);  //使用了 this 指针,调用函数的 } }

a1.xx(); a1.xx.call(window);

var jj = a1.xx;

jj(); //效果跟a1.xx.call(window); 同样//试试下边代码

var x=99; function xb(){ this.x=100; this.a = (function(){return this.x}).call(this); //new 的时候推行了,无名氏函数被 实例化的对象 调用 this.b = (function(){return this.x})(); //new 的时候试行了,佚名函数被window调用 this.method = function(){return this.x;} }

var xbObj = new xb(); console.log(xbObj.x); console.log(xbObj.a); console.log(xbObj.b); console.log(xbObj.method());

专一区分调用函数的对象、函数评释时的语法情状、函数调用语句的语法遭受那多少个概念

 

1、调用函数的指标(或然说函数的调用格局)决定了函数运维时函数体内的this指针指向什么人

2、函数注解时的语法情况调整了函数运维时的寻访权限

3、函数调用语句的语法遇到调节了函数是不是真的能够被调用及哪天被调用(独有函数在有个别语法情形是可知的,那几个函数技巧被调用)

函数在运作时,发生贰个 arguments 对象足以访谈传入函数内的参数,arguments 有壹天性质能够本着函数本人:arguments.callee.

函数运转时,函数的 caller 属性可以针对本函数调用言语所在函数,举例,a函数在b函数体内被调用,则当a函数运维时,a.caller就指向了b函数,如果a 函数在全局碰到中被调用则 a.caller=null

arguments 和a.caller 的值与函数的每三遍调用直白关联,他们皆以在函数运维时发出的,只可以在函数体内访谈。

IE8及IE8以下浏览器中,a 函数的内的 arguments.caller( IE9之后这一个天性被移除) 指向 a.caller 实行时的 arguments (arguments.caller.callee === a.caller),

七、字符串实时深入分析中的函数调用:eval()、new Function()、setTimeout()、setInterval()

eval() 与 window.eval()

代码如下:

function a(){     console.log('out of b'); } function b(){     function a(){ console.log("in b"); }     var f = function(){ a(); };     eval('a()'); // in b     window.eval('a()'); //out of b ,ie 678 in b, ie 9 out of b     (new Function('a();'))(); //out of b     setTimeout('a()',1000);   // out of b
    setTimeout(f,2000);// in b } b();

eval() 中的代码试行于eval() 语句所处的成效域内:

代码如下:

var Objinit = function(){   var param = 123;   return {           execute:function(codes){                 eval(codes);           },           setCallback:function(f){                this.callback = f;           },           fireCallback:function(){                this.callback && this.callback.call(this);           },          getParam:function(){              return param;          }    } };

 

var obj = Objinit (); var param = 'outerParam'; console.log(param,obj.getParam()); //outerParam 123 obj.execute('param = 456'); console.log(param,obj.getParam()); //outerParam 456 obj.setCallback(function(){ eval("param = 8888")}); obj.fireCallback(); console.log(param,obj.getParam()); //8888 456 obj.setCallback(function(){ eval("eval(param = 9999)")}); obj.fireCallback(); console.log(param,obj.getParam()); //9999 456eval()

字符串中分析出的代码运在 eval 所在的功效域,window.eval() 则是运作在顶级成效域(低版本 chrome 和 低于IE9 则同 eval()).

 

IE 中 ,window.execScript();  相当于 window.eval()

new Function()、setTimeout()、setInterval()  的首先个字符串参数所深入分析获得的代码,都是在顶尖效用域试行。

八、函数闭包

要知道函数闭包,先掌握 js 的废物自动回收机制。

number、string、boolean、undefined、null 在运算和赋值操作中是复制传值,而指标类型的数量按援引传值,

js 的同八个指标型数码或然被频仍援引,假使有些对象不再被引述,可能五个对象时期互相引用之外不在被第三方所引述,浏览器会活动释放其占领的内部存款和储蓄器空间。

函数被引述:函数被赋为其余对象的属性值,或许函数内部定义的数量在该函数外被应用,闭包的变异基于后一种境况。

  代码如下:

var f;

function fun(){

var a =1;

f = function(){ return a;};

}

fun(); //发生二个闭包

f(); //  闭包中 a=2

f(); // 闭包中 a =3  ,模拟静态变量

在 fun 内 表明的佚名函数赋给 fun 外的变量 f,该无名氏函数内选取了在 fun 内证明的变量 a,于是 f能够访谈 变量 a,为了保持这种访问权限(f施行时须求访谈a,但何时试行未定), fun() 实行完成发生的变量 a 不能够被保释(除非f 中的函数被放出),于是发生了四个闭包(变量 a 被封闭了,供 f 使用)。

 

发生闭包的要害是,一个在函数 A内的扬言的函数 B被盛传 A 之外,並且 B 函数内接纳了在 函数A 内生成的数目(注解或按值传参),

函数B传出函数A之外的诀窍有多样,如:

代码如下:

function fun(){    var a =1;

return {a:123,b:456, c: function(){ return a;} };

}

var f = fun();

f.c(); //a=2

 

广义上来说,函数运营时都会产生闭包,非常少在函数外被援引时,闭包的生命周期非常的短:函数推行完成即自由。

闭包的独立性:固然由同叁个函数发生的多个闭包也是互相独立的

  代码如下:

function fun(){ 

var a =1;

return function(){ return a;};

}

var f1 =  fun(); //一份闭包

var f2 = fun(); //另一份闭包

alert(f1()); //2

 alert(f1()); //3

 alert(f2()); //2

 alert(f2()); //3

这两份闭包中的变量 a 是见仁见智的数目,每产生一份闭包, fun() 推行了三回,  变量证明语句也施行了贰次。

 

js oop 编制程序中闭包能够用来模拟私有成员、构造单体类

 代码如下:

function MakeItem(name,val){  var myName,myVal; //私有属性 

//私有方法  function setName(name){      myname=name; }

 //私有 方法 function setVal(val){     myVal=val;  }

 //实施new构造对象时调用内部私有方法 setName(name); setVal(val);

//公共艺术 this.getName=function(){     return myName; }

 this.getVal=function(){     return myVal;  } }

var obj = new MakeItem("name",100); obj.myname; //undefined 不可能在外围访谈私有属性 obj.getName(); //ok

下边是一种单体类创设方式

 代码如下:

var Singleton = (function(){

    var instance = null; //在闭包中保存单体类的实例

    var args = null;

    var f = function(){

        if(!instance){

            if(this===window){               

               args = Array.prototype.slice.call(arguments,0);               

                instance = new arguments.callee();

            }else{

               this.init.apply(this,args||arguments);

                instance = this;

            }

        }

        return instance;

    };

    f.prototype = {

        init:function(a,b,c){

            this.a = a;

            this.b = b;

            this.c = c;      

            this.method1 = function(){ console.log("method 1"); };

            this.method1 = function(){ console.log("method 1"); };

            console.log("init instance");

        }

    };

    f.prototype.constructor = f.prototype.init;

    return f;

 

})();

//单体的利用 var obj1 =  Singleton(1,2,3);

var obj2 = new Singleton();

var obj3 = new Singleton();

console.log(obj1===obj2,obj2===obj3); //true

console.log(obj1);

//五个单体类注脚函数

var SingletonDefine= function(fun){

    return (function(){

        var instance = null;

        var args = null;      

        var f = function(){

            if(!instance){

                if(this===window){

                    args = Array.prototype.slice.call(arguments,0);                   

                    instance = new arguments.callee();

                }else{

                    fun.apply(this,args||arguments);                   

                    instance = this;

                }

            }

            return instance;

        };

 

        f.prototype = fun.prototype;

        f.prototype.constructor = fun;            

        return f;

    })();

};

var fun = function(a,b,c){

    this.a = a;

    this.b = b;

    this.c = c;

    this.method1 = function(){ console.log("method 1"); };

    console.log("init instance");

};

fun.prototype.method2 = function(){ console.log('method 2'); };

//单体类注脚函数用法 var Singleton = SingletonDefine(fun);

var obj1 =  Singleton(8,9,10);

var obj2 = new Singleton();

var obj3 = new Singleton(3,2,1);

console.log(obj1===obj2,obj2===obj3);

console.log(obj1);

//console.log(obj1.toSource()); //firefox

obj1.method1();

obj1.method2();

IE6 的内部存款和储蓄器败露与闭包

 

在IE 6 中,非原生js对象(DOM 等)的大循环引用会产生内部存款和储蓄器走漏,使用闭包时只要涉及非 js 原生对象引用时要稳重。

function fun(){

var node = document.getElementById('a'); node.onclick = function(){ alert(node.value); };

node = null; //打断循环引用幸免内部存款和储蓄器走漏

node 保存的是 DOM 对象,DOM对象存在于 fun 之外(况兼直接留存,即便去除也只是从文书档案树移出),fun 实践后发出闭包,也构成DOM对象与回调函数的巡回引用(node-function-node),在IE 6 下发生内部存款和储蓄器走漏。

本文由星彩网app下载发布于前端技术,转载请注明出处:函数及作用域总结介绍,javascript函数及作用域的

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。