JS 匿名函数

在ECMAScript中,有三种不同的函数类型,并且他们都有自己的特点

函数声明(简写FD)是这样的一个函数:

1、有一个特定的名称
2、在源码中的位置:要么处于程序级(Program level),要么处于其它函数的主体(FunctionBody)中
3、在进入上下文阶段创建
4、影响变量对象
5、以下面的方式声明
function exampleFunc() {
  ...
}

这种类型的函数最重要的特点就是它影响变量对象(存储在变量对象的上下文中),这个特性也说明了第二个很重要的观点(它是变量对象特性的结果)在代码执行阶段它们已经可用(因为FD在进入上下文阶段已经存在于VO中——代码执行之前)。

另外一个重点知识点是上述定义中的第二点——函数声明在源码中的位置:

// function can be declared:
// 1) directly in the global context
function globalFD() {
  // 2) or inside the body
  // of another function
  function innerFD() {}
}

只有这2个位置可以声明函数,也就是说:不可能在表达式位置或一个代码块中定义它。

函数表达式:

1、在源码中须出现在表达式的位置
2、有可选的名称
3、不会影响变量对象
4、在代码执行阶段创建
这种函数类型的主要特点在于它在源码中总是处在表达式的位置。最简单的一个例子就是一个赋值声明:

var foo = function () {
  ...
};

该例演示是让一个匿名函数表达式赋值给变量foo,然后该函数可以用foo这个名称进行访问——foo()。

同时和定义里描述的一样,函数表达式也可以拥有可选的名称:

var foo = function _foo() {
  ...
};

需要注意的是,在外部FE通过变量“foo”来访问——foo(),而在函数内部(如递归调用),有可能使用名称“_foo”。

如果FE有一个名称,就很难与FD区分。但是,如果你明白定义,区分起来就简单明了:FE总是处在表达式的位置。在下面的例子中我们可以看到各种ECMAScript 表达式:


// in parentheses (grouping operator) can be only an expression
(function foo() {});

// in the array initialiser – also only expressions
[function bar() {}];

// comma also operates with expressions
1, function baz() {};

表达式定义里说明:FE只能在代码执行阶段创建而且不存在于变量对象中,让我们来看一个示例行为:


// FE is not available neither before the definition
// (because it is created at code execution phase),

alert(foo); // "foo" is not defined

(function foo() {});

// nor after, because it is not in the VO

alert(foo);  // "foo" is not defined

相当一部分问题出现了,我们为什么需要函数表达式?答案是很显然的——在表达式中使用它们,”不会污染”变量对象。最简单的例子是将一个函数作为参数传递给其它函数。

function foo(callback) {
  callback();
}

foo(function bar() {
  alert('foo.bar');
});

foo(function baz() {
  alert('foo.baz');
});

在上述例子里,FE赋值给了一个变量(也就是参数),函数将该表达式保存在内存中,并通过变量名来访问(因为变量影响变量对象),如下:

var foo = function () {
  alert('foo');
};

foo();

另外一个例子是创建封装的闭包从外部上下文中隐藏辅助性数据(在下面的例子中我们使用FE,它在创建后立即调用):

var foo = {};

(function initialize() {

  var x = 10;

  foo.bar = function () {
    alert(x);
  };

})();

foo.bar(); // 10;

alert(x); // "x" is not defined

我们看到函数foo.bar(通过[[Scope]]属性)访问到函数initialize的内部变量“x”。同时,“x”在外部不能直接访问。在许多库中,这种策略常用来创建”私有”数据和隐藏辅助实体。在这种模式中,初始化的FE的名称通常被忽略:


(function () {

  // initializing scope

})();

还有一个例子是:在代码执行阶段通过条件语句进行创建FE,不会污染变量对象VO。

var foo = 10;

var bar = (foo % 2 == 0
  ? function () { alert(0); }
  : function () { alert(1); }
);

bar(); // 0

函数的封装调用

//函数的封装调用
    var car = {
        color:function(){
            alert('红色');
        },

        runOrspeed:function(){
            alert('120km/h');
        }
    }

调用如下:

<input type="button" value="车对象" onclick="car.color()"/>

匿名函数的实例:

// 匿名函数的封装调用
    var car = {};
    (function(name){
        car.color = function(carcolor){
            alert('车是'+carcolor + '的');
        }
        alert(name);
    }('测试匿名函数'));

    car.color('蓝色');

外部调用实例:

<input type="button" value="车对象" onclick="car.color('蓝色')"/>

控制div的显示隐藏

// 通过id找到html的dom对象 设置css属性 控制 div显示
document.getElementById('jtime').setAttribute('style','display: ;');
//通过id找到html的dom对象 设置css属性 控制 div隐藏     
document.getElementById('first').setAttribute('style','display:none');
//通过id找到html的dom对象 动态改变html内容
document.getElementById('time').innerHTML=12;
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值