web前端|js教程
JavaScript,js,局部
web前端-js教程
定义在函数体外的都属于全局变量,定义在函数体内的属于局部变量。这里的定义是指通过var声明的。
html5网页源码,ubuntu 源仓库镜像,爬虫代理怎么避免,php和php的前景,石嘴山seo公司lzw
JavaScript有隐含的全局概念,意味着你不声明的任何变量都会成为一个全局对象属性。例如:
mysql php源码,ubuntu误删家目录,爬虫爬家庭地址,php连接iis,seo 在家工作lzw
function test(){ myname = "huming"; alert(myname);}test();// "huming"alert(myname);//"huming"
两个结果是一样的,说明myname是一个全局变量。
项目源码下载,ubuntu命令解压rar,怎么下载tomcat解压版,爬虫引起牢狱,php面向对象的规范,seo裤lzw
那么,隐式全局变量和明确定义的全局变量有没有区别呢。。答案肯定是有的,看下面的例子:
// 定义三个全局变量var global_test1 = 1;global_test2 = 2; // 反面教材(function () { global_test3 = 3; // 反面教材}());// 试图删除delete global_test1; // falsedelete global_test2; // truedelete global_test3; // true// 测试该删除alert(typeof global_test1); // "number"alert(typeof global_test2); // "undefined"alert(typeof global_test3); // "undefined"
由上面的例子可以看出:在函数之外通过var定义的global_test1不能被删除,而没有经过var定义的global_test2和global_test3都被删除了(无论是否是在函数体内创建)。
总结来说,在函数体外通过var声明的全局变量不能被删除,而隐式全局变量是可以删除的。
这里要注意了:JavaScript有一种行为叫做“hoisting”(悬置/置顶解析/预解析)。
我们通过一个例子来说明:
var myname = "huming"; //声明全局变量function test() { alert(myname); var myname = "local_huming"; alert(myname);}test();
你猜两次alert的内容一致吗??显然不一致,一致还用说吗。。实际输出是:”undefined”, “local_huming”。
上面的例子等同于
var myname = "huming"; //声明全局变量function test() {var myname;alert(maname);
myname = "local_huming";alert(myname); // "local"}test();
第一次alert输出的myname并不是你以为的全局变量,而是和它在一个作用域(一个函数体)内的局部变量。虽然它还没有被声明,但被当作是声明了。这就是所谓的“hoisting”。
这样应该就明白了吧。当你在函数体中使用了一个变量,又在之后重新声明的话,就可能产生错误。
书写规范:
function test() { var a = 1, b = 2, c = a + b, d = {}, e, f; // function body...}
好处在于:
1、所有局部变量都定义在函数开始,方便查找;
2、防止变量在定义之前使用的逻辑错误。
如何替换?
在如何提高JavaScript性能这个问题上,大家最常听到的建议应该就是尽量使用局部变量(local variables)来代替全局变量(global variables)。在我从事Web开发工作的九年时间里,这条建议始终萦绕在我的耳边,并且从来没有质疑过,而这条建议的基础,则来自于 JavaScript处理作用域(scoping)和标识符解析(identifier resolution)的方法。
首先我们要明确,函数在JavaScript中具体表现为对象,创建一个函数的过程,其实也就是创建一个对象的过程。每个函数对象都有一个叫做 [[Scope]]的内部属性,这个内部属性包含创建函数时的作用域信息。实际上,[[Scope]]属性对应的是一个对象(Variable Objects)列表,列表中的对象是可以从函数内部访问的。比如说我们建立一个全局函数A,那么A的[[Scope]]内部属性中只包含一个全局对象(Global Object),而如果我们在A中创建一个新的函数B,那么B的[[Scope]]属性中就包含两个对象,函数A的Activation Object对象在前面,全局对象(Global Object)排在后面。
当一个函数被执行的时候,会自动创建一个可以执行的对象(Execution Object),并同时绑定一个作用域链(Scope Chain)。作用域链会通过下面两个步骤来建立,用于进行标识符解析。
首先将函数对象[[Scope]]内部属性中的对象,按顺序复制到作用域链中。
其次,在函数执行时,会创建一个新的Activation Object对象,这个对象中包含了this、参数(arguments)、局部变量(包括命名的参数)的定义,这个Activation Object对象会被置于作用域链的最前面。
在执行JavaScript代码的过程中,当遇到一个标识符,就会根据标识符的名称,在执行上下文(Execution Context)的作用域链中进行搜索。从作用域链的第一个对象(该函数的Activation Object对象)开始,如果没有找到,就搜索作用域链中的下一个对象,如此往复,直到找到了标识符的定义。如果在搜索完作用域中的最后一个对象,也就是全局对象(Global Object)以后也没有找到,则会抛出一个错误,提示用户该变量未定义(undefined)。这是在ECMA-262标准中描述的函数执行模型和标识符解析(Identifier Resolution)的过程,事实证明,大部分的JavaScript引擎确实也是这样实现的。需要注意的是,ECMA-262并没有强制要求采用这种结构,只是对这部分功能加以描述而已。