参考 http://www.educity.cn/wenda/54753.html

已实验验证结果正确。

1、下列哪些正确?(B、C)
  A.function(){
  alert("Here!");
  }();
  B.(function(){
  alert("Here!");
  })();
  C.(function(){
  alert("Here!");
  }());

下面也已经实验验证结果正确。

2、下列哪个结果是正确的?(A、B、C、D)
  A.(function(a1,a2){
  alert("Here!"+(a1+a2));
  })(1,2);
  B.(function(a1,a2){
  alert("Here!" +(a1+a2));
  }(1,2));
  C.void function(a1,a2){
  alert("Here!" +(a1+a2));
  }(1,2);
  D.var f = function(a1,a2){
  alert("Here!" +(a1+a2));
  }(1,2); 注:A 、B、C与D四种格式都正确,前两者属于同种情况的不同写法,后两种是将函数对象的返回值赋给其他变量,C是忽略函数返回值,而D正相反!

下面这个的结果也验证,但是注意,稍稍改一下,效果就很大差别。

function Foo() {
var a = 123;
this.a = 456;
(function() {
console.log(a); //
console.log(this.a); // undefined
})();
};
var f = new Foo(); 结果:
123
undefined (1)匿名函数可以直接访问到外层署名函数(Foo)中的变量(使用关键字var定义的),但不能访问外层署名函数的属性(使用关键字this定义的);

稍微改一下,把Foo前面的new去掉,直接调用Foo,如下:

function Foo() {
var a = 123;
this.a = 456;
(function() {
console.log(a); //
console.log(this.a); // undefined
})();
};
var f = Foo(); 结果:
123
456

然后在最后分别加上console.log(f)看看f被赋予什么内容:

var f = new Foo();
console.log(f); 结果:
Foo { a: 456 } var f = Foo();
console.log(f); 结果:
undefined

开始写自己代码的时候,发现了下面的情况。本来以为是node跟原生js的区别呢,看来不是。

/**
* Created by baidu on 16/10/24.
*/
function test(){
var a = 123;
this.a = 456;
return (function(p1,p2){
console.log(a);
console.log(this.a);
return p1+p2;
})(1,2);
};
(function(){
console.log(test());
}()); 用node跑:
123
456
3

内部要访问数据,可以通过传参数(方法一):

function Foo() {
var a = 123;
this.a = 456;
(function(_this) {
console.log(a); //
console.log(_this.a); //
})(this);
};
var f = new Foo(); 结果:
123
456

另外,注意下面这种情况:

(function() {
var a = 123;
this.a = 456;
(function() {
console.log(a); //
console.log(this.a); //
})();
})(); 结果:
123
456 (1) 匿名函数既可以直接访问外层匿名函数中的变量,又直接可以访问外层匿名函数中的属性,而匿名函数却不可以直接访问外层已命名函数中的属性;

访问没有定义过的this.xxx,也是很有意思的:

/**
* Created by baidu on 16/10/24.
*/ function Foo() {
var a = 123;
this.a = 456;
(function() {
console.log(a); //
console.log(this.a); // undefined
this.b = 789;
})();
(function() {
console.log(this.b); //
})();
};
var f = new Foo();
(function() {
console.log(this.a); // undefined
console.log(this.b); //
})();
结果:

123
undefined
789
undefined
789

后面分析。

再来一个里外都是匿名函数的情况:

/**
* Created by baidu on 16/10/24.
*/ (function() {
var a = 123;
this.a = 456;
(function() {
console.log(a); //
console.log(this.a); //
this.b = 789;
})();
(function() {
console.log(this.b); //
})();
})();
(function() {
console.log(this.a); //
console.log(this.b); //
})(); 结果:
123
456
789
456
789

通过上面两个例子的对比及分析,可以看出如下结论:

(1)匿名函数(即用两个小括号括起来的部分)位于一个执行上下文,不论这些代码放在哪个位置上。

再比较下面两种情况:

情况1:

function Foo() {
(function() {
this.b = 789;
})();
(function() {
console.log(this.b); //
console.log(b); //
var a = 0;
console.log(a); //
})();
}
var f = new Foo();
(function() {
console.log(this.b); //
console.log(b); //
})(); 结果:
789
789
0
789
789

情况2:

/**
* Created by baidu on 16/10/24.
*/ function Foo() {
(function() {
this.b = 789;
})();
(function() {
console.log(this.b); //
console.log(b); //undefined
var b = 0;
console.log(b); //
})();
}
var f = new Foo();
(function() {
console.log(this.b); //
console.log(b); //
})(); 结果:
789
undefined
0
789
789

从以上对比,可以看出:

没有加 this取值时,如果当前 {} 中不存在同名的局部变量,则等同于加 this 处理;如果当前 {} 中存在同名的局部变量,则按常规处理。
上面第二例中,b会打印出undefined,是因为在{}出现了b,并且是在后面出现的,当前还是undefined.

以上,是一些实验结果。

JS里面匿名函数的调用 & 变量作用域的实验的更多相关文章

  1. JS函数定义与匿名函数的调用

    一.函数声明.函数表达式.匿名函数 函数声明:function fnName () {…};使用function关键字 声明一个函数,再指定一个函数名,叫函数声明. 函数表达式 var fnName ...

  2. JS 之匿名函数

    匿名函数以及闭包 匿名函数就是没有名字的函数.闭包是指有权访问另一个函数作用域中的变量的函数.创建闭包的常见方式是在一个函数的内部创建另一个函数.闭包会携带包含它的函数的作用域,因此会比其他函数占用更 ...

  3. [js]js代码执行顺序/全局&私有变量/作用域链/闭包

    js代码执行顺序/全局&私有变量/作用域链 <script> /* 浏览器提供全局作用域(js执行环境)(栈内存) --> 1,预解释(仅带var的可以): 声明+定义 1. ...

  4. js基础 js自执行函数、调用递归函数、圆括号运算符、函数声明的提升 js 布尔值 ASP.NET MVC中设置跨域

    js基础 目录 javascript基础 ESMAScript数据类型 DOM JS常用方法 回到顶部 javascript基础 常说的js包括三个部分:dom(文档document).bom(浏览器 ...

  5. javascript匿名函数自调用

    // 匿名函数的自调用 /*var f1 = function() { console.log('我是一个匿名函数!'); }*/ // f1(); // 上面是定义一个匿名函数,然后调用,其实上面就 ...

  6. 总结下js中匿名函数的写法~好几天没写博客了。。。

    小哥最近很是心烦啊,不仅仅要继续以现任前端小白,未来前端攻城狮的身份苦逼学习,还要用剩余的时间去完成毕业设计.早知如此,当初我为毛要报考数学这么个苦逼专业....昨天一整天的时间在研究毕设,感觉代码已 ...

  7. js 匿名函数-立即调用的函数表达式

    先提个问题, 单独写匿名函数为什么报错?return 匿名函数 为什么不报错? 如图: 第二种情况在 f 还没有执行的时候,就报错了,,,当然这得归因于函数声明语句声明提前(发生在代码执行之前)的原因 ...

  8. JavaScript函数定义和调用 变量作用域

     本文是笔者在看廖雪峰老师JavaScript教程时的个人总结   JavaScript中函数定义可以是这样的格式 function 函数名(参数) {     函数体 } 也可以是这样的格式     ...

  9. JavaScript 中的匿名函数((function() {})();)与变量的作用域

    以前都是直接用前端框架Bootstrap,突然想看看Javascript,发现javascript是个非常有趣的东西,这里把刚碰到的一个小问题的理解做下笔录(废话不多说,上代码). /** * Exa ...

随机推荐

  1. href=#与href=javascriptvoid(0)的区别

    #"包含了一个位置信息 默认的锚点是#top 也就是网页的上端 而javascript:void(0)  仅仅表示一个死链接 这就是为什么有的时候页面很长浏览链接明明是#可是跳动到了页首 而 ...

  2. mysql 权限 备份

    mysqldump常用于MySQL数据库逻辑备份. 1.各种用法说明 A. 最简单的用法: mysqldump -uroot -pPassword [database name] > [dump ...

  3. 从3D Studio Max导入物体 Importing Objects From 3D Studio Max

    原地址:http://game.ceeger.com/Manual/HOWTO-ImportObjectMax.html If you make your 3D objects in 3dsMax, ...

  4. delphi 中几种多线程操作方式

    在了解多线程之前我们先了解一下进程和线程的关系 一个程序至少有一个主进程,一个进程至少有一个线程. 为了保证线程的安全性请大家看看下面介绍 Delphi多线程同步的一些处理方案大家可以参考:http: ...

  5. ZOJ3554 A Miser Boss(dp)

    给你n个工件,然后有A,B,C三个工厂,然后它们加工第i个工件所需要的时间分别为a[i],b[i],c[i],然后现在要你利用三间工厂加工所有的零件,要求是任何时间工厂都不能停工,而且一定要三间同时做 ...

  6. POJ 2531 Network Saboteur (枚举+剪枝)

    题意:给你一个图,图中点之间会有边权,现在问题是把图分成两部分,使得两部分之间边权之和最大. 目前我所知道的有四种做法: 方法一:状态压缩 #include <iostream> #inc ...

  7. sql server 存储过程,事务

    1.存储过程,事务 CREATE PROCEDURE Proc_ceshi @id int, ), @returnval int output AS BEGIN SET NOCOUNT ON; Set ...

  8. 一步完成 MySQL 向 Redis 迁移

    从mysql搬一个大表到redis中,你会发现在提取.转换或是载入一行数据时,速度慢的让你难以忍受.这里我就要告诉一个让你解脱的小技巧.使用“管道输出”的方式把mysql命令行产生的内容直接传递给re ...

  9. 【BZOJ1878】[SDOI2009]HH的项链 离线BIT

    1878: [SDOI2009]HH的项链 Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义 ...

  10. Spring学习总结(0)——Spring详解

    一:spring的基本用法: 1,关于spring容器: spring容器是Spring的核心,该 容器负责管理spring中的java组件, ApplicationContext ctx  = ne ...