首页 > 代码库 > JS里面匿名函数的调用 & 变量作用域的实验

JS里面匿名函数的调用 & 变量作用域的实验

参考 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); // 123
        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); // 123
        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); // 123
        console.log(_this.a); // 456
    })(this);
};
var f = new Foo();

结果:
123
456

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

(function() {
    var a = 123;
    this.a = 456;
    (function() {
        console.log(a); // 123
        console.log(this.a); // 456
    })();
})();

结果:
123
4561) 匿名函数既可以直接访问外层匿名函数中的变量,又直接可以访问外层匿名函数中的属性,而匿名函数却不可以直接访问外层已命名函数中的属性;

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

/**
 * Created by baidu on 16/10/24.
 */

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

123
undefined
789
undefined
789

后面分析。

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

/**
 * Created by baidu on 16/10/24.
 */

(function() {
    var a = 123;
    this.a = 456;
    (function() {
        console.log(a); // 123
        console.log(this.a); // 456
        this.b = 789;
    })();
    (function() {
        console.log(this.b); // 789
    })();
})();
(function() {
    console.log(this.a); // 456
    console.log(this.b); // 789
})();

结果:
123
456
789
456
789

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

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

再比较下面两种情况:

情况1:

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

结果:
789
789
0
789
789

情况2:

/**
 * Created by baidu on 16/10/24.
 */

function Foo() {
    (function() {
        this.b = 789;
    })();
    (function() {
        console.log(this.b); // 789
        console.log(b); //undefined
        var b = 0;
        console.log(b); // 0
    })();
}
var f = new Foo();
(function() {
    console.log(this.b); // 789
    console.log(b); // 789
})();

结果:
789
undefined
0
789
789

从以上对比,可以看出:

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

以上,是一些实验结果。

 

JS里面匿名函数的调用 & 变量作用域的实验