javascript的作用域链,js作用域和作用域链
看了很多文章,终于明白了Javascript的链作用域。
非常感谢你,Laruence,风雪之角。
事实上,JavaScript链作用域的描述,包括JS权威指南,都有点太冗长了——但这是准确的:Javascript中的函数运行在它们定义的作用域中,而不是在它们执行的作用域中。
这句话有点难懂,但是程序的设计基本上是为了简单和容易理解。还记得JS里那句经典的话吗,一切都是对象。
说白了,chain scope其实是Javascript的一个特性:父函数的所有变量都可以在子函数中访问。当然也包括全局变量window(一般函数定义函数a(){}其实是window对象的一个子函数)。另外,函数有两种定义方式,其实略有不同:var a=function(){}和function a(){}。稍后我会解释它们的不同之处。
所以我们在看Crockford的《Javascript语言本质》的时候提到,要在函数中定义变量,要养成一个好习惯,请直接在函数的开头定义变量。JS在这方面和其他语言的要求不同——尽量延迟变量的定义(在使用之前)。
让我们来看看laruence提供的例子:
varname= laruencefunction echo(){ alert(name);varname= eve警报(名称);警觉(年龄);} echo();这个例子其实很混乱(会让人误以为输出结果是:laruence,eve,error其实结果是:undefined,eve,error),关键是因为echo()函数中定义的var name=eve 。但实际上,换一种说法,这个例子很清楚:
varname= laruencefunction echo(){ varname;警报(名称);name= eve警报(名称);警觉(年龄);} echo();其实上面的函数用JS引擎解析的时候会这样解析。如果你是初学者,其实可以这么理解。但是如果你有编程其他程序的经验,比如java。很容易被常规思维所困。PS:被困的是我。所以,根据克罗克福德的建议,定义变量,请在函数的顶部!
还记得之前的问题吗?var=function () {}和function a(){}的区别。
它们的区别和变量的定义是相似的。一切都是对象。
在调用函数的时候它们基本上是等价的,但是如果调用了函数,那么在定义函数之前就会出现问题。其实区别就在于等号和函数关键字。
而var函数定义在预编译中是高级的,var只是一个占位符。具体赋值要等到JS引擎执行完这行。函数定义会在JS引擎预编译阶段直接放到调用对象中。
或者举个例子:
示例1:
警报(回声);//函数echo(){ return 1;};
函数echo(){ return 1;};
警戒(一);//undefinedvar a=function(){ return 1;};
所以一个函数的定义也可以引出一个句子。请把函数的定义放在最上面(先定义再调用)!
其实是习惯问题。JS中一些代码的好习惯和其他语言不一样。建议你看Javascript语言的本质。当开始学习一门语言时,最好从欣赏优秀的代码开始。在JS中,大家都喜欢用一系列混乱的代码来加深理解,这其实是一种误解。
另一方面,这个关键词laruence的解释非常简洁到位:‘谁叫它就是这个’。英文版稍微详细一点:“在Java脚本中,这种方式引用我们正在执行的函数的“所有者”,或者更确切地说,引用函数是其方法的对象。”,英文解释:“在JavaScript中,这总是指我们执行的函数的所有者,更准确地说,这是指一个函数的方法对象”
看看下面的例子,也有误导性:
函数a(){
g _ value= uk
}
a();
alert(g _ value);
实际上,友好的写法应该是这样的:
函数a(){
this.g _ value= uk
}
a();//a.apply(这个);
alert(this . g _ value);
这个关键字不同于其他语言。首先,它不是对实例的引用,而是调用它的上下文。上例中的a()相当于a . apply(this);
call apply的用法和call apply一样,区别在于参数传递。一种是逐个传递参数,另一种是以类数组的形式传递参数(注意这个地方是类数组)。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。