- 浏览: 7960889 次
- 性别:
- 来自: 广州
-
文章分类
- 全部博客 (2425)
- 软件工程 (75)
- JAVA相关 (662)
- ajax/web相关 (351)
- 数据库相关/oracle (218)
- PHP (147)
- UNIX/LINUX/FREEBSD/solaris (118)
- 音乐探讨 (1)
- 闲话 (11)
- 网络安全等 (21)
- .NET (153)
- ROR和GOG (10)
- [网站分类]4.其他技术区 (181)
- 算法等 (7)
- [随笔分类]SOA (8)
- 收藏区 (71)
- 金融证券 (4)
- [网站分类]5.企业信息化 (3)
- c&c++学习 (1)
- 读书区 (11)
- 其它 (10)
- 收藏夹 (1)
- 设计模式 (1)
- FLEX (14)
- Android (98)
- 软件工程心理学系列 (4)
- HTML5 (6)
- C/C++ (0)
- 数据结构 (0)
- 书评 (3)
- python (17)
- NOSQL (10)
- MYSQL (85)
- java之各类测试 (18)
- nodejs (1)
- JAVA (1)
- neo4j (3)
- VUE (4)
- docker相关 (1)
最新评论
-
xiaobadi:
jacky~~~~~~~~~
推荐两个不错的mybatis GUI生成工具 -
masuweng:
(转)JAVA获得机器码的实现 -
albert0707:
有些扩展名为null
java 7中可以判断文件的contenttype了 -
albert0707:
非常感谢!!!!!!!!!
java 7中可以判断文件的contenttype了 -
zhangle:
https://zhuban.me竹板共享 - 高效便捷的文档 ...
一个不错的网络白板工具
http://www.cnblogs.com/onepixel/p/5036369.html
一、作用域(scope)
所谓作用域就是:变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。
复制代码
1 function scope(){
2 var foo = "global";
3 if(window.getComputedStyle){
4 var a = "I'm if";
5 console.log("if:"+foo); //if:global
6 }
7 while(1){
8 var b = "I'm while";
9 console.log("while:"+foo);//while:global
10 break;
11 }
12 !function (){
13 var c = "I'm function";
14 console.log("function:"+foo);//function:global
15 }();
16 console.log(
17 foo,//global
18 a, // I'm if
19 b, // I'm while
20 c // c is not defined
21 );
22 }
23 scope();
复制代码
(1)scope函数中定义的foo变量,除过自身可以访问以外,还可以在if语句、while语句和内嵌的匿名函数中访问。 因此,foo的作用域就是scope函数体。
(2)在javascript中,if、while、for 等代码块不能形成独立的作用域。因此,javascript中没有块级作用域,只有函数作用域。
但是,在JS中有一种特殊情况:
如果一个变量没有使用var声明,window便拥有了该属性,因此这个变量的作用域不属于某一个函数体,而是window对象。
复制代码
1 function varscope(){
2 foo = "I'm in function";
3 console.log(foo);//I'm in function
4 }
5 varscope();
6 console.log(window.foo); //I'm in function
复制代码
二、作用域链(scope chain)
所谓作用域链就是:一个函数体中嵌套了多层函数体,并在不同的函数体中定义了同一变量, 当其中一个函数访问这个变量时,便会形成一条作用域链(scope chain)。
复制代码
1 foo = "window";
2 function first(){
3 var foo = "first";
4 function second(){
5 var foo = "second";
6 console.log(foo);
7 }
8 function third(){
9 console.log(foo);
10 }
11 second(); //second
12 third(); //first
13 }
14 first();
复制代码
当执行second时,JS引擎会将second的作用域放置链表的头部,其次是first的作用域,最后是window对象,于是会形成如下作用域链:
second->first->window, 此时,JS引擎沿着该作用域链查找变量foo, 查到的是"second"
当执行third时,third形成的作用域链:third->first->window, 因此查到的是:"frist"
特殊情况:with语句
JS中的with语句主要用来临时扩展作用域链,将语句中的对象添加到作用域的头部。with语句结束后,作用域链恢复正常。
复制代码
1 foo = "window";
2 function first(){
3 var foo = "first";
4 function second(){
5 var foo = "second";
6 console.log(foo);
7 }
8 function third(obj){
9 console.log(foo); //first
10 with (obj){
11 console.log(foo); //obj
12 }
13 console.log(foo); //first
14 }
15 var obj = {foo:'obj'};
16 third(obj);
17 }
18 first();
复制代码
在执行third()时,传递了一个obj对象,obj中有属性foo, 在执行with语句时,JS引擎将obj放置在了原链表的头部,于是形成的作用域链如下:
obj->third->first->window, 此时查找到的foo就是obj中的foo,因此输出的是:"obj", 而在with之前和之后,都是沿着原来的链表进行查找,从而说明,在with语句结束后,作用域链已恢复正常。
三、this 关键字
在一个函数中,this总是指向当前函数的所有者对象,this总是在运行时才能确定其具体的指向, 也才能知道它的调用对象。
这句话总结了关于this的一切,切记,切记,切记!(ps:重要的事情说三遍!)
复制代码
1 window.name = "window";
2 function f(){
3 console.log(this.name);
4 }
5 f();//window
6
7 var obj = {name:'obj'};
8 f.call(obj); //obj
复制代码
在执行f()时,此时f()的调用者是window对象,因此输出"window"
f.call(obj) 是把f()放在obj对象上执行,相当于obj.f(),此时f中的this就是obj,所以输出的是"obj"
四、实战应用
code1:
复制代码
1 var foo = "window";
2 var obj = {
3 foo : "obj",
4 getFoo : function(){
5 return function(){
6 return this.foo;
7 };
8 }
9 };
10 var f = obj.getFoo();
11 f(); //window
复制代码
code2:
复制代码
var foo = "window";
var obj = {
foo : "obj",
getFoo : function(){
var that = this;
return function(){
return that.foo;
};
}
};
var f = obj.getFoo();
f(); //obj
复制代码
code1和code2是对this和scope最好的总结,如果对于运行结果有疑惑,欢迎讨论!
代码解析:
复制代码
code1:
执行var f = obj.getFoo()返回的是一个匿名函数,相当于:
var f = function(){
return this.foo;
}
f() 相当于window.f(), 因此f中的this指向的是window对象,this.foo相当于window.foo, 所以f()返回"window"
code2:
执行var f = obj.getFoo() 同样返回匿名函数,即:
var f = function(){
return that.foo;
}
唯一不同的是f中的this变成了that, 要知道that是哪个对象之前,先确定f的作用域链:f->getFoo->window 并在该链条上查找that,此时可以发现that指代的是getFoo中的this, getFoo中的this指向其运行时的调用者,从var f = obj.getFoo() 可知此时this指向的是obj对象,因此that.foo 就相当于obj.foo,所以f()返回"obj"
一、作用域(scope)
所谓作用域就是:变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。
复制代码
1 function scope(){
2 var foo = "global";
3 if(window.getComputedStyle){
4 var a = "I'm if";
5 console.log("if:"+foo); //if:global
6 }
7 while(1){
8 var b = "I'm while";
9 console.log("while:"+foo);//while:global
10 break;
11 }
12 !function (){
13 var c = "I'm function";
14 console.log("function:"+foo);//function:global
15 }();
16 console.log(
17 foo,//global
18 a, // I'm if
19 b, // I'm while
20 c // c is not defined
21 );
22 }
23 scope();
复制代码
(1)scope函数中定义的foo变量,除过自身可以访问以外,还可以在if语句、while语句和内嵌的匿名函数中访问。 因此,foo的作用域就是scope函数体。
(2)在javascript中,if、while、for 等代码块不能形成独立的作用域。因此,javascript中没有块级作用域,只有函数作用域。
但是,在JS中有一种特殊情况:
如果一个变量没有使用var声明,window便拥有了该属性,因此这个变量的作用域不属于某一个函数体,而是window对象。
复制代码
1 function varscope(){
2 foo = "I'm in function";
3 console.log(foo);//I'm in function
4 }
5 varscope();
6 console.log(window.foo); //I'm in function
复制代码
二、作用域链(scope chain)
所谓作用域链就是:一个函数体中嵌套了多层函数体,并在不同的函数体中定义了同一变量, 当其中一个函数访问这个变量时,便会形成一条作用域链(scope chain)。
复制代码
1 foo = "window";
2 function first(){
3 var foo = "first";
4 function second(){
5 var foo = "second";
6 console.log(foo);
7 }
8 function third(){
9 console.log(foo);
10 }
11 second(); //second
12 third(); //first
13 }
14 first();
复制代码
当执行second时,JS引擎会将second的作用域放置链表的头部,其次是first的作用域,最后是window对象,于是会形成如下作用域链:
second->first->window, 此时,JS引擎沿着该作用域链查找变量foo, 查到的是"second"
当执行third时,third形成的作用域链:third->first->window, 因此查到的是:"frist"
特殊情况:with语句
JS中的with语句主要用来临时扩展作用域链,将语句中的对象添加到作用域的头部。with语句结束后,作用域链恢复正常。
复制代码
1 foo = "window";
2 function first(){
3 var foo = "first";
4 function second(){
5 var foo = "second";
6 console.log(foo);
7 }
8 function third(obj){
9 console.log(foo); //first
10 with (obj){
11 console.log(foo); //obj
12 }
13 console.log(foo); //first
14 }
15 var obj = {foo:'obj'};
16 third(obj);
17 }
18 first();
复制代码
在执行third()时,传递了一个obj对象,obj中有属性foo, 在执行with语句时,JS引擎将obj放置在了原链表的头部,于是形成的作用域链如下:
obj->third->first->window, 此时查找到的foo就是obj中的foo,因此输出的是:"obj", 而在with之前和之后,都是沿着原来的链表进行查找,从而说明,在with语句结束后,作用域链已恢复正常。
三、this 关键字
在一个函数中,this总是指向当前函数的所有者对象,this总是在运行时才能确定其具体的指向, 也才能知道它的调用对象。
这句话总结了关于this的一切,切记,切记,切记!(ps:重要的事情说三遍!)
复制代码
1 window.name = "window";
2 function f(){
3 console.log(this.name);
4 }
5 f();//window
6
7 var obj = {name:'obj'};
8 f.call(obj); //obj
复制代码
在执行f()时,此时f()的调用者是window对象,因此输出"window"
f.call(obj) 是把f()放在obj对象上执行,相当于obj.f(),此时f中的this就是obj,所以输出的是"obj"
四、实战应用
code1:
复制代码
1 var foo = "window";
2 var obj = {
3 foo : "obj",
4 getFoo : function(){
5 return function(){
6 return this.foo;
7 };
8 }
9 };
10 var f = obj.getFoo();
11 f(); //window
复制代码
code2:
复制代码
var foo = "window";
var obj = {
foo : "obj",
getFoo : function(){
var that = this;
return function(){
return that.foo;
};
}
};
var f = obj.getFoo();
f(); //obj
复制代码
code1和code2是对this和scope最好的总结,如果对于运行结果有疑惑,欢迎讨论!
代码解析:
复制代码
code1:
执行var f = obj.getFoo()返回的是一个匿名函数,相当于:
var f = function(){
return this.foo;
}
f() 相当于window.f(), 因此f中的this指向的是window对象,this.foo相当于window.foo, 所以f()返回"window"
code2:
执行var f = obj.getFoo() 同样返回匿名函数,即:
var f = function(){
return that.foo;
}
唯一不同的是f中的this变成了that, 要知道that是哪个对象之前,先确定f的作用域链:f->getFoo->window 并在该链条上查找that,此时可以发现that指代的是getFoo中的this, getFoo中的this指向其运行时的调用者,从var f = obj.getFoo() 可知此时this指向的是obj对象,因此that.foo 就相当于obj.foo,所以f()返回"obj"
发表评论
-
微信开发工具中时间问题的小坑
2018-02-07 19:07 840刚开始用微信小程序开发工具,每次运行任何应用,都报这个错误: ... -
三篇不错的介绍CSS GRID的文章
2017-12-06 09:08 565三篇不错的介绍CSS GRID的文章: http://www. ... -
双因素认证(2FA)教程
2017-11-03 09:16 1578http://www.ruanyifeng.com/blog/ ... -
es6 中的export
2017-08-20 08:00 834https://juejin.im/post/5998625f ... -
markdown中的空格
2017-08-20 07:53 1709即使手动输入空格, 也是很不推荐的方法。我推荐全角空格,切换 ... -
(转)讲真,别再使用JWT了
2017-08-17 23:21 1021不错的好文: http://insights.thoughtw ... -
(转)手把手教你WebStorm+chrome实现时时调试刷新
2017-08-15 10:50 3043参考: http://jingyan.baidu.com/ar ... -
IntelliJ Idea 2017 免费激活方法
2017-08-15 09:38 93591. 到网站 http://idea.lanyus.com/ ... -
前端框架这么多,该何去何从?
2017-08-04 07:17 653http://insights.thoughtworkers. ... -
记录一个HTML 5画拓扑图的商业公司
2017-07-18 19:56 854http://qunee.com/ DEMO:http:// ... -
vue 2例子学习收集
2017-07-16 11:46 10161 vue2.0手撸闲鱼App https://githu ... -
(收藏)虚拟DOM内部是如何工作的
2017-07-13 22:08 604虚拟DOM内部是如何工作的 https://segmentfa ... -
最近看到的几篇精彩JAVASCRIPT博客文章推荐
2017-07-11 07:10 580【深度长文】JavaScript数组所有API全解密 http ... -
jsonp 跨域原理:深入浅出 jsonp
2017-07-10 19:55 1439https://lzw.me/a/jsonp.html jso ... -
(转)深度长文-JavaScript数组所有API全解密
2017-07-08 19:59 830深度长文-JavaScript数组所有API全解密 http: ... -
(收藏)网页导出PDF的方案
2017-07-06 07:13 1007(收藏)网页导出PDF的方案 https://yiqiwuli ... -
Chromium 新的弹窗机制以及 HTML 的 <dialog> 元素
2017-06-28 12:37 1157https://juejin.im/post/59525195 ... -
国内一个不错的大屏UI设计厂家
2017-06-03 19:43 3164http://www.lanlanwork.com/dp.ph ... -
canvas仿芝麻信用分仪表盘
2017-05-28 20:21 1608canvas仿芝麻信用分仪表盘 https://segment ... -
(转)CSS 变量教程
2017-05-10 21:12 587http://www.ruanyifeng.com/blog/ ...
相关推荐
JavaScript主要有两种作用域: 1. **全局作用域**: 全局变量在整个脚本中都可用,即使在函数内部也可以访问。但创建过多的全局变量可能导致命名冲突,因此通常应避免。 2. **局部作用域**: 在函数内部声明的...
JavaScript有两种类型的局部作用域:函数作用域和块级作用域。函数作用域是指在函数内部声明的变量只在该函数内部有效。而块级作用域则是通过使用大括号({})定义的,例如if语句、循环语句或者单独的代码块中。在...
在JS中有全局作用域和函数作用域,而在Nodejs中也自己的作用域,分为全局作用域(global)和模块作用域。 js作用域: 以前学js的时候我们的全局对象是window,如: var a = 10; console.log(window.a); 我们定义的...
首先需要明确,JavaScript中存在两种变量作用域:全局作用域和函数作用域。 1. 全局作用域 全局作用域指的是在任何函数外部声明的变量,这种变量在整个程序中的任何地方都可以被访问和修改。如果在程序中未经声明就...
总结来说,执行环境和作用域链是JavaScript中处理变量和函数作用范围的核心机制。全局环境提供了一个全局的变量和函数存储区域,而局部环境则在函数调用时创建,为函数提供了私有的变量空间。作用域链保证了代码可以...
函数作用域是JavaScript中的另一个关键概念,它指出了函数运行时可以访问变量的作用域。具体来说,函数内的变量和函数在其内部是可访问的,而函数外的变量和函数则不可访问。同时,函数中的代码在执行时会首先处理...
当函数被定义在另一个函数内部时,内部函数将持有外部函数作用域的引用,即使外部函数已经执行完毕,只要内部函数还在使用这些变量,它们就不会被垃圾回收机制回收。这使得闭包在创建私有变量和方法时非常有用,它还...
例如,通过设置`this`,我们可以确保函数操作的数据仅限于期望的对象,而不是全局作用域。 总的来说,理解JavaScript函数的四种形态对于编写高效、安全的代码至关重要。它们不仅影响函数的行为,还与面向对象编程、...
闭包的主要特点在于它可以访问到定义时的作用域,即使该作用域在函数外部是不可见的。 首先,闭包的形成条件是:在一个函数内部定义另一个函数,并且内部函数引用了外部函数的变量。在这个例子中: ```javascript ...
在执行过程中,JavaScript通过作用域链来解析标识符(变量和函数名)。它从作用域链的前端开始,沿着链路逐级查找,直到找到标识符为止。如果在局部作用域找不到,会继续在上一层(外部)作用域查找,直到全局作用域...
在JavaScript中,嵌套函数拥有对父函数作用域的访问权限,这使得嵌套函数可以读取外部函数的变量。例如,在给定的代码片段中,`g`作为`f`的嵌套函数,可以访问`f`中定义的变量`x`。 其次,闭包是基于词法作用域和...
在JavaScript编程语言中,变量名和函数名重名是一个常见的问题,这主要涉及到JavaScript的预解析(hoisting)机制和作用域规则。本文将深入探讨这个问题,并解释为什么在某些情况下,代码可能会出现“is not a ...
在JavaScript编程中,闭包是一个非常重要的概念,它的特性使得函数可以访问到外部函数作用域中的变量。然而,闭包如果使用不当,非常容易引起内存泄漏问题。内存泄漏会逐渐消耗计算机的可用内存,进而影响程序的性能...
例如,在`f1`函数中,变量`i`、`j`和`k`都是在各自的作用域内定义的,即使在循环或条件语句之后,它们仍然可以被访问,因为它们属于函数作用域,而非临时的代码块作用域。 预编译是JavaScript执行的一个重要步骤。...