JavaScript高级程序设计学习笔记——函数

函数表达式

定义函数的两种方式

函数声明:

function functionName(arg0, arg1, arg2) {
    //函数体
}

利用函数声明方式定义的函数,有一个重要特征函数声明提升

sayHi();  //可以把函数声明放在调用它的语句后面
function sayHi(){
    alert("Hi!");
}

函数表达式

var functionName = function(arg0, arg1, arg2){
    //函数体
};

创建的一个函数将其赋值给一个变量
这种函数叫匿名函数(拉欧姆函数)

sayHi(); //错误:函数还不存在
var sayHi = function(){
    alert("Hi!");
};

闭包

闭包是指有权访问另一个函数作用域中的变量的函数。(啥意思?)
通俗点就是:
闭包是一个函数,这个函数可以访问另一个函数中的变量。

如何创建闭包
在一个函数中创建另一个函数。

function createComparisonFunction(propertyName) {
    return function(object1, object2){           //这个匿名函数是一个闭包
        var value1 = object1[propertyName];  //可以访问外层函数的propertyName
        var value2 = object2[propertyName];
        if (value1 < value2){
            return -1;
        } else if (value1 > value2){
            return 1;
        } else {
            return 0;
        }
    };
}   

为什么内部函数可以访问外部函数的变量?
内部函数的作用域链包含外部函数的作用域链。

几个名词

  • 执行环境:函数被调用时,会创建一个执行环境以及相应的作用域链
  • 作用域链:一个指向变量对象的指针列表
  • 活动对象:一个对象,包含arguments和其他命名参数
  • 全局变量对象:
//创建函数
var compareNames = createComparisonFunction("name");
//调用函数
var result = compareNames({ name: "Nicholas" }, { name: "Greg" });

这里写图片描述
从图中可以看到:
内部函数包含外部函数的作用域链,因此内部函数被返回时,也可以访问到外部函数的变量。
还可以看到:
闭包会携带其他函数的作用域,因此会占用更多的内存。

闭包与变量

一个经典的题目

function func() {
    var result = new Array();
    for(var i = 0; i < 10; i ++){
        result[i] = function() {
            return i;
        }
    }
    return result;
}
var res = func();
console.log(res[0]());   //此时的结果是什么?

func函数中返回了10个闭包,每个闭包都会包含func的活动对象—— i ,
在执行完循环体后,i的值就变成了10 ,所以这10个闭包的返回值都是10。

如果想返回0,1,2,3,4,5,6,7,8,9该怎么办

  1. 再增加一层闭包
  2. 立即执行函数
function func2() {
    var result = new Array();

    for(var i = 0; i < 10; i++) {
    result[i] = function(num){  //立即执行函数
        return function() { //result得到的是这一层闭包
            return num;  
        }
    }(i);
}

    return result;
}

var res2 = func2();
console.log(res2[0]());    // 0
块级作用域

可以利用闭包和立即执行函数创建一个块级作用域

(function(){
    //这里是块级作用域
})();
(function(){})  

利用圆括号包起来代表函数表达式,函数表达式后再接一个圆括号代表立即执行函数。

function(){}()

这种写法是错的,以function开头代表函数声明,函数声明不能跟圆括号

私有变量
function Person(name){
    this.getName = function(){
        return name;
    };
    this.setName = function (value) {
        name = value;
    };
}
var person = new Person("Nicholas");
alert(person.getName()); //"Nicholas"
person.setName("Greg");
alert(person.getName()); //"Greg"

getName(),setName()为Person的闭包,闭包的作用域包含它自己的作用域、包含函数的作用域和全局作用域。

模块模式

为单例创建私有变量和特权方法。
单例:只有一个实例的对象。

var application = function(){
    //私有变量和函数
    var components = new Array();
    //初始化
    components.push(new BaseComponent());
    //公共
    return {
        getComponentCount : function(){
            return components.length;
        },
        registerComponent : function(component){
            if (typeof component == "object"){
            components.push(component);
            }
        }
    };
}();
增强的模块模式
var application = function(){
    //私有变量和函数
    var components = new Array();
    //初始化
    components.push(new BaseComponent());
    //创建application 的一个局部副本
    var app = new BaseComponent();
    //公共接口
    app.getComponentCount = function(){
        return components.length;
    };
    app.registerComponent = function(component){
        if (typeof component == "object"){
        components.push(component);
        }
    };
    //返回这个副本
    return app;
}();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值