闭包以及暴露接口---学习笔记

闭包      :  函数可以访问它被创建时所处的上下文环境。---《JavaScript语言精粹》

产生原理:  JavaScript中没有块级作用域,只有函数作用域,函数中任何位置定义的参数和变量在函数内的任何地方都是可见的,在函数外不可见。

使用方法:  可以通过在函数内部创建局部变量,实现变量的私有化。(外部不可见)

注意事项:  内部函数访问外部函数的变量时访问的是实际变量(值为外部函数返回时变量的值)。

知识点   :  ①只要内部函数需要,外部函数中的变量不会在外部函数返回后销毁。(多了浪费内存)

②通过定义内部函数实现对内部变量信息的查询和修改,实现接口的暴露。

举个例子:

var myObject = (function(){
    var value=0;
    return {
        getValue: function(){
            return value;
        },
        setValue: function(v){
            if (typeof v === ‘number‘){
                 value = v;
            }
        }
    };
}());    

这段代码得到一个myObject对象,包含两个方法,只有这两个方法可以获取或者修改value变量,没有其他办法可以访问到value变量。
这个value变量我们叫私有变量,这两个可以访问私有变量的共有方法就叫做特权方法

再举个例子:

//构造一个函数,本义是通过内部函数返回一个函数数组,数组中每一项都是一个函数//数组项函数会返回当前的数组索引
//但是最后每一项的函数都会得到返回10

var eg2 = function(){
    var i,
    result = new Array();                   

    for(i=0; i<10; i += 1){
        result[i] = function(){
            return i;
        }
    }

    return result;
};

为什么最后数组中每一项的函数都会返回10呢?因为内部的匿名函数访问的是变量i而不是函数创建时i的值,在for循环执行完后变量i中保存的值为10,最后外部函数返回的result数组中的每一项的函数中返回的变量i的值也就为10。

可以修改成这样解决:

//在for循环之外创建一个辅助函数,返回一个会返回传入的值的函数

var eg2 = function(){
    var result = new Array();                   

    var helper = function(e){
        return function(){
            return e;
        }
    };

    var i;
    for(i=0; i<10; i += 1){
        result[i] = helper(i);
    }

    return result;
};

在for循环中每次调用helper()函数时,传入变量i,由于函数参数是按值传递的,helper()就会将当前的变量i的值复制给局部变量e,然后返回一个会返回变量e的函数。

这里的变量e是每个数组项函数的局部变量,各自保存着各自不同的值。

时间: 2024-08-06 10:13:09

闭包以及暴露接口---学习笔记的相关文章

OpenCV(C++接口)学习笔记4-Mat::operator = 的陷阱

当我们想要将一个Mat对象的数据复制给另一个Mat对象时,应该怎么做呢? 我们发现,OpenCV提供了重载运算符Mat::operator = ,那么,是否按照下列语句就可以轻松完成对象的赋值呢? Mat a; Mat b = a; 答案是否定的! 我们可以从reference manual 中看到: Mat::operator = Provides matrix assignment operators. C++: Mat& Mat::operator=(const Mat& m) Pa

OpenCV(C++接口)学习笔记2-像素级的图像操作

1.通过成员函数at(int y, int x)访问 这种方法需要知道像素保存的格式. (1) 这是为模板类型的函数,因为一个函数的返回类型只有在运行时才会知道. (2)这个函数返回的是一个向量即Vector,故有下标的操作. image.at<uchar>(j,i)= 255; 在单通道图像中,采用以上语句可以获取图像(i,j)处的灰度值(注:先行后列,一般用j表示行(rows),i表示列(cols)).如果是灰度图像的话,只需要更改一个数据就可以了.如果是rgb图像的话,就要用"

OpenCV(C++接口)学习笔记1-图像的读取、显示、保存

OpenCV在2.0版本之后添加了C++接口函数,之前学习的都是C语言的接口函数,现在OpenCV已经发展到2.4.9版本了,所以决定学习C++接口函数,跟上节奏. 1.创建图像 cv::Mat image; 采用类cv::Mat来定义图像变量或矩阵变量. 当然你也可以指定图像的大小: cv::Mat img(240,320,CV_8U,cv::Scalar(100)); 参数CV_8U中的U代表unsigned,而S代表signed.对于三通道彩色图像可以用CV_8UC3.你也可以声明16或3

JavaScript闭包(Closure)学习笔记

闭包(closure)是JavaScript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 下面就是我的学习笔记,对于JavaScript初学者应该是很有用的. 一.变量的作用域 要理解闭包,首先必须理解JavaScript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. JavaScript语言的特殊之处,就在于函数内部可以直接读取全局变量. var n=999; function f1() { alert(n); } f1(); // 999 另一方面,在函数

PHP 开发 APP 接口 学习笔记与总结 - APP 接口实例 [3] 首页 APP 接口开发方案 ② 读取缓存方式

以静态缓存为例. 修改 file.php line:11 去掉 path 参数(方便),加上缓存时间参数: public function cacheData($k,$v = '',$cacheTime = 0){ //文件名 $filename = $this->_dir.$k.'.'.self::EXT; ..... line:25 把缓存时间设置为 11 位的数字,如果不满 11 位,则在时间前面补 0.再把缓存时间和缓存内容进行拼接: $cacheTime = sprintf('%011

PHP 开发 APP 接口 学习笔记与总结 - APP 接口实例 [2] 首页 APP 接口开发方案 ① 读取数据库方式

方案一:读取数据库方式 从数据库读取信息→封装→生成接口数据 应用场景: 数据时效性比较高的系统 方案二:读取缓存方式 从数据库获取信息(第一次设置缓存或缓存失效时)→封装(第一次设置缓存或缓存失效时)→返回数据 ↓                                              ↑ 缓存(缓存生效时)     →   →    →    → 方案三:定时读取缓存方式(crontab 定时任务) 封装并返回数据 ↑ 数据库→crontab→缓存 ↑ http 请求 ==

使用java调用hadoop接口学习笔记

[简介] 由于hadoop是安装在linux系统,因此需要在linux系统使用eclipse开发java.现在很多公司都要求有在linux上开发java的经验 ,因此这也是一个练手的绝好机会.学习hadoop不仅仅是学习了hadoop,我相信等hadoop入门,linux也入门了,shell也入门了,linux上开发java也会了,或许这就是学习的魅力吧,让人欲罢不能!废话不多说,进入正题. [安装eclipse] 工欲善其事,必先利其器,想在linux上用java开发hadoop程序,搭建环境

.net接口学习笔记

1.接口的声明 接口的声明不能包含:数据成员,静态变量:只能包含如下类型的静态成员函数的声明:方法,属性,事件,索引器.声明中不能包含任何实现的代码,而在每个成员成名的主体后,必须使用分号. 接口声明可以有任何的修饰符public.protect.internl或private. 接口的成员是隐式的public,不允许任何访问修饰符,包括public. 1 Public Interface IMyInterface 2 { 3 //接口成员是隐式的public,并且只有声明 4 int Meth

HttpSessionActivationListener接口 学习笔记

实现了HttpSessionActivationListener接口的 JavaBean 对象可以感知自己被活化和钝化的事件当绑定到 HttpSession 对象中的对象将要随 HttpSession 对象被钝化之前,web 服务器调用如下方法sessionWillPassivate(HttpSessionBindingEvent event) 方法当绑定到 HttpSession 对象中的对象将要随 HttpSession 对象被活化之后,web 服务器调用该对象的 void sessionD