JavaScript函数模式详解


Posted in Javascript onNovember 07, 2014

在javascript中,函数是一类对象,这表示他可以作为参数传递给其他函数;此外,函数还可以提供作用域。

js函数基础部分:javascript学习笔记(四)function函数部分

创建函数的语法

命名函数表达式

//命名函数表达式

var add = function add(a,b){

    return a+b;

};

函数表达式

//又名匿名函数

var add = function(a,b){

    return a+b;

};

函数的声明

function foo(){

    //code here

}  //这里可以不需要分号

在尾随的分号中,函数表达式应总是使用分号,而函数的声明中并不需要分号结尾.

函数声明与表达式

函数的提升(hoisting)

函数声明的行为并不等同于命名函数表达式,其区别在于提升(hoisting)行为,看下面例子:

<script type="text/javascript">

    //全局函数

    function foo(){alert("global foo!");}

    function bar(){alert('global bar');}
    function hoist(){

        console.log(typeof foo);//function

        console.log(typeof bar);//undefined
        foo();//local foo!

        bar();//TypeError: 'undefined' is not a function 
        //变量foo以及实现者被提升

        function foo(){

            alert('local foo!');

        }
        //仅变量bar被提升,函数实现部分 并未被提升

        var bar = function(){

            alert('local bar!');

        };

    }

    hoist(); 

</script>

对于所有变量,无论在函数体的何处进行声明,都会在内部被提升到函数顶部。而对于函数通用适用,其原因在于函数只是分配给变量的对象。

提升,顾名思义,就是把下面的东西提到上面。在JS中,就是把定义在后面的东西(变量或函数)提升到前面中定义。 从上面的例子可以看出,在函数hoist内部中的foo和bar移动到了顶部,从而覆盖了全局foo和bar函数。局部函数bar和foo的区别在于,foo被提升到了顶部且能正常运行,而bar()的定义并没有得到提升,仅有它的声明被提升,所以,当执行bar()的时候显示结果为undefined而不是作为函数来使用。

即时函数模式

函数也是对象,因此它们可以作为返回值。使用自执行函数的好处是直接声明一个匿名函数,立即使用,省得定义一个用一次就不用的函数,而且免了命名冲突的问题,js中没有命名空间的概念,因此很容易发生函数名字冲突,一旦命名冲突以最后声明的为准。

模式一:

<script>

    (function () {

        var a = 1;

        return function () {

            alert(2);

        };

    }()());//弹出2,第一个圆括号自执行,第二个圆括号执行内部匿名函数

</script>

模式二:自执行函数变量的指向

<script type="text/javascript">

        var result = (function () {

            return 2;

        })();//这里已执行了函数
        alert(result);//result 指向了由自执行函数的返回值2;如果弹出result()会出错

</script>

模式三:嵌套函数

<script type="text/javascript">

        var result = (function () {

            return function () {

                return 2;

            };

        })();
 alert(result());//alert(result)的时候弹出2;alert(result())的时候弹出function(){return 2}

</script>

模式四:自执行函数把它的返回值赋给变量

    var abc = (function () {

            var a = 1;

            return function () {

                return ++a;

            }

        })();//自执行函数把return后面的函数返回给变量

   alert(abc());//如果是alert(abc)就会弹出return语句后面的代码;如果是abc(),则会执行return后面的函数

模式五:函数内部执行自身,递归

// 这是一个自执行的函数,函数内部执行自身,递归

function abc() { abc(); }

回调模式

回调函数:当你将一个函数write()作为一个参数传递给另一个函数call()时,那么在某一时刻call()可能会执行(或者调用)write()。这种情况下,write()就叫做回调函数(callback function)。

异步事件监听器

回调模式有许多用途,比如,当附加一个事件监听器到页面上的一个元素时,实际上是提供了一个回调函数的指针,该函数将会在事件发生时被调用。如:

document.addEventListener("click",console.log,false);

上面代码示例展示了文档单击事件时以冒泡模式传递给回调函数console.log()的

javascript特别适用于事件驱动编程,因为回调模式支持程序以异步方式运行。

超时

使用回调模式的另一个例子是,当使用浏览器的window对象所提供的超时方法:setTimeout()和setInterval(),如:

<script type="text/javascript">

    var call = function(){

        console.log("100ms will be asked…");

    };

    setTimeout(call, 100);

</script>

库中的回调模式

当设计一个js库时,回调函数将派上用场,一个库的代码应尽可能地使用可复用的代码,而回调可以帮助实现这种通用化。当我们设计一个庞大的js库时,事实上,用户并不会需要其中的大部分功能,而我们可以专注于核心功能并提供“挂钩形式”的回调函数,这将使我们更容易地构建、扩展,以及自定义库方法

Curry化

Curry化技术是一种通过把多个参数填充到函数体中,实现将函数转换为一个新的经过简化的(使之接受的参数更少)函数的技术。———【精通JavaScript】

简单来说,Curry化就是一个转换过程,即我们执行函数转换的过程。如下例子:

<script type="text/javascript">

    //curry化的add()函数

    function add(x,y){

        var oldx = x, oldy = y;

        if(typeof oldy == "undefined"){

            return function(newy){

                return oldx + newy;

            };

        }

        //完全应用

        return x+y;

    }

    //测试

    typeof add(5);//输出"function"

    add(3)(4);//7

    //创建并存储一个新函数

    var add2000 = add(2000);

    add2000(10);//输出2010

</script>

当第一次调用add()时,它为返回的内部函数创建了一个闭包。该闭包将原始的x和y值存储到私有变量oldx和oldy中。

现在,我们将可使用任意函数curry的通用方法,如:

<script type="text/javascript">

    //普通函数

    function add(x,y){

        return x + y;

    }

    //将一个函数curry化以获得一个新的函数

    var newadd = test(add,5);

    newadd(4);//9
    //另一种选择,直接调用新函数

    test(add,6)(7);//输出13

</script>

何时使用Curry化

当发现正在调用同一个函数时,并且传递的参数绝大多数都是相同的,那么该函数可能是用于Curry化的一个很好的候选参数

Javascript 相关文章推荐
用JavaScript实现UrlEncode和UrlDecode的脚本代码
Jul 23 Javascript
js实现图片放大缩小功能后进行复杂排序的方法
Nov 08 Javascript
原生js的弹出层且其内的窗口居中
May 14 Javascript
JavaScript中的bold()方法使用详解
Jun 08 Javascript
javascript中的3种继承实现方法
Jan 27 Javascript
用js动态添加html元素,以及属性的简单实例
Jul 19 Javascript
Dropzone.js实现文件拖拽上传功能(附源码下载)
Nov 22 Javascript
Node.js如何使用Diffie-Hellman密钥交换算法详解
Sep 05 Javascript
解决包含在label标签下的checkbox在ie8及以下版本点击事件无效果兼容的问题
Oct 27 Javascript
浅谈vuex的基本用法和mapaction传值问题
Nov 08 Javascript
jquery ajax 请求小技巧实例分析
Nov 11 jQuery
vant picker+popup 自定义三级联动案例
Nov 04 Javascript
JavaScript代码复用模式详解
Nov 07 #Javascript
JavaScript中的style.cssText使用教程
Nov 06 #Javascript
JavaScript组合拼接字符串的效率对比测试
Nov 06 #Javascript
5个书写JavaScript代码的坏习惯,看看你中枪了没?
Nov 06 #Javascript
javascript解析json实例详解
Nov 05 #Javascript
JavaScript中发布/订阅模式的简单实例
Nov 05 #Javascript
JavaScript不刷新实现浏览器的前进后退功能
Nov 05 #Javascript
You might like
php中convert_uuencode()与convert_uuencode函数用法实例
2014/11/22 PHP
php使用curl打开https网站的方法
2015/06/17 PHP
thinkphp多层MVC用法分析
2015/12/30 PHP
PHP二维数组实现去除重复项的方法【保留各个键值】
2017/12/21 PHP
Laravel框架Eloquent ORM修改数据操作示例
2019/12/03 PHP
Javascript调试工具(下载)
2007/01/09 Javascript
Firefox和IE浏览器兼容JS脚本写法小结
2008/07/07 Javascript
JavaScript 基础问答三
2008/12/03 Javascript
Ajax请求在数据量大的时候出现超时的解决方法
2014/02/27 Javascript
jquery实现弹出层遮罩效果的简单实例
2014/03/03 Javascript
推荐 21 款优秀的高性能 Node.js 开发框架
2014/08/18 Javascript
jquery和js实现对div的隐藏和显示方法
2014/09/26 Javascript
JQuery选择器、过滤器大整理
2015/05/26 Javascript
JavaScript给input的value赋值引发的关于基本类型值和引用类型值问题
2015/12/07 Javascript
JavaScript 隐性类型转换步骤浅析
2018/03/15 Javascript
vue对storejs获取的数据进行处理时遇到的几种问题小结
2018/03/20 Javascript
Vue.js最佳实践(五招助你成为vuejs大师)
2018/05/04 Javascript
微信小程序之swiper滑动面板用法示例
2018/12/04 Javascript
在Vant的基础上实现添加表单验证框架的方法示例
2018/12/05 Javascript
layui实现数据分页功能(ajax异步)
2019/07/27 Javascript
layUI的验证码功能及校验实例
2019/10/25 Javascript
Vue中el-form标签中的自定义el-select下拉框标签功能
2020/04/20 Javascript
JavaScript位置参数实现原理及过程解析
2020/09/14 Javascript
Tornado服务器中绑定域名、虚拟主机的方法
2014/08/22 Python
Python实现批量执行同目录下的py文件方法
2019/01/11 Python
对Python中一维向量和一维向量转置相乘的方法详解
2019/08/26 Python
python如何快速生成时间戳
2020/07/21 Python
Python3.9.1中使用match方法详解
2021/02/08 Python
澳大利亚当地最大的时装生产商:Cue
2018/08/06 全球购物
室内设计专业学生的自我评价分享
2013/11/27 职场文书
小学毕业感言300字
2014/02/19 职场文书
保护环境倡议书
2014/04/14 职场文书
学校纪律作风整改措施思想汇报
2014/10/11 职场文书
2015年超市收银员工作总结
2015/04/25 职场文书
机关单位2016年法制宣传日活动总结
2016/04/01 职场文书
flex布局中使用flex-wrap实现换行的项目实践
2022/06/21 HTML / CSS