闭包和高阶函数

小知识:

var test3={
a:‘asd‘
}
console.log(test3[‘a‘]);

Array.prototype.slice.call(arguments)能将具有length属性的对象转成数组

相当于给数组的原型添加全局方法

 var toArray = function(s){
 2     try{
 3         return Array.prototype.slice.call(s);
 4     } catch(e){
 5             var arr = [];
 6             for(var i = 0,len = s.length; i < len; i++){
 7                 //arr.push(s[i]);
                   arr[i] = s[i];  //据说这样比push快
 8             }
 9              return arr;
10     }
11 }

一个闭包例子

function test(){
    var a=12;
    function innertest(){
        console.log(a);
    }
    return innertest;
}
var t = test();
t();//12

这是因为test函数返回一个innertest函数 并且将其赋值给 t变量 即使该函数位于外部但innertest函数 依然保留着在test中的内部作用域依然能够访问内部的属性值

因此innertest拥有该函数内部的闭包

一般来说函数执行完函数后 js的 GC垃圾自动回收机制会回收不再使用的函数作用域单在这里由于闭包而阻止销毁

注意:不建议使用闭包占内存

    //备忘函数
function cache(fn){
    const ca = {};
    return function(...args){
        const key = JSON.stringify(args);
       return ca[key]||(ca[key] = fn.apply(fn,args))
    }
}

//进行运算
function add(a){
  return a;
}
var adder = cache(add);
adder(1);

解释:

add赋值算出值

JSON.stringify将传递的参数转换为字符串作为建
fn.apply(fn,args)) 调用闭包作用域中的参数执行该函数

需要改进:如果无限存储元素则相当耗内存 建议使用持久化存储 比如浏览器的 cookie 或者LocalStorage

高阶函数:传入的参数有函数或者返回中的有函数

函数作为返回值主要是利用闭包保持作用域

函数科里化:
function test(fn,...test1){
    return function(...test2){
        return fn.apply(null,test1.concat(test2));
    }
}
function sayHello(age,username,s){
    console.log(11);
   console.log(age+""+username+""+s);
}//运算前提前传递参数
var s = test(sayHello,12);
s(‘webcyh‘,‘he‘);
 
柯里化是固定部分参数,返回一个接受剩余参数的函数,也称为部分计算函数,目的是为了减少适用范围,创建一个正对性更强的函数,核心思想是把多参数传入的函数拆成单参数或者部分参数函数,内部在调用下一个单参数或者部分函数,依次处理剩下的参数
反柯里化
function test(fn){
    return function(args,...a){
        return fn.apply(args,a);
    }
}

var push =test(Array.prototype.push);//提前传递的参数 或者上下文到最后是用
function check(){
    push(arguments,5);
    console.log(arguments);
}
check(1,2,1);
ES5 和ES6作用域差别ES6 出现了块级作用域例子:
var arr=[];
    for(var i=0;i<4;i++){
       arr[i]=function(){
           console.log(i);
       }
    }
    arr[2]();//返回4
    /*这里var 声明的为函数作用域在这里也就是全局变量 后面调用的函数 打印的也是全局变量最后的结果4*/
    var arr=[];
    for(let i=0;i<4;i++){
       arr[i]=function(){
           console.log(i);
       }
    }
    arr[2]();//返回2
    /*这里let  为ES6语法 这里的i作用域为块级 也就是该变量知识在该次循环中有效每次循环都是一个新的变量*/

ES6 不存在变量提升

// let、const 命令不存在变量提升
console.log(boo) // 报错 ReferenceError
let boo = 2

ES6 暂时性死区

在块作用域中 用let 或者const 声明一个变量之前 该变量不可用

ES6不允许重复声明

ES6箭头函数

总结:

当函数有只有一个参数时 可以忽略 括号

如果 没有参数时 括号不可忽略

如果函数体只有返回值 可以忽略花括号和return关键字

如果 返回值是一个对象字面型 返回值要添加括号

箭头函数不会自己创建自己的this 只有在定义函数时继承自上一级的this

例子:

function test(){
        var age=12;
        setInterval(()=>{
            this.age++;
            console.log(age);
        },1000);
    }
    var t = new test();


原文地址:https://www.cnblogs.com/webcyh/p/11291747.html

时间: 2024-10-08 08:04:02

闭包和高阶函数的相关文章

[Node.js] 闭包和高阶函数

原文地址:http://www.moye.me/2014/12/29/closure_higher-order-function/ 引子 最近发现一个问题:一部分写JS的人,其实对于函数式编程的概念并不是太了解.如下的代码片断,常常让他们觉得不可思议: OAuth2Server.prototype.authCodeGrant = function (check) { var self = this; return function (req, res, next) { new AuthCodeG

(三)闭包和高阶函数

虽然javascript是一门面向对象的编程语言,但这门语言同时也同时拥有许多函数式语言的特性. 函数式语言的鼻祖是LISP,javascript设计之初参考了LISP两大方言之一的Schenme,引入了Lambda表达式,闭包,高阶函数等特性.使用这些特性,我们就可以灵活的编写javascript代码. 一:闭包 对于javascript程序员来说,闭包(closure)是一个难懂又必须征服的概念.闭包的形成与变量作用域以及变量的声明周期密切相关. 1.变量作用域 变量的作用域就是指变量的有效

JavaScript设计模式与开发实践-读书笔记(3)闭包和高阶函数

闭包(closure) 闭包的形成与变量的作用域以及变量的生存周期密切相关. 变量的作用域,就是指变量的有效范围. 全局变量和局部变量. 在JavaScript中,函数可以用来创造函数作用域. 变量的生存周期,全局变量的生命周期是永久的,除非我们主动销毁这个全局变量. 对于在函数体内用var关键字声明的局部变量来说,当退出函数时,这些局部变量即失去了它们的价值,它们都会随着函数调用的结束而被销毁. 利用闭包我们可以完成许多奇妙的工作. 闭包的作用: 1.封转变量 闭包可以帮助我们把一些不需要暴露

2016.3.3(Spark框架预览,Scala部分应用函数、闭包、高阶函数,关于语义分析的一些心得)

一.Spark框架预览 主要有Core.GraphX.MLlib.Spark Streaming.Spark SQL等几部分. GraphX是进行图计算与图挖掘,其中主流的图计算框架现在有:Pregal.HAMA.Giraph(这几部分采用超步即同步的方式),而GraphLab与Spark GraphX采用异步的方式进行.它与Spark SQL进行协作时,一般是用SQL语句来进行ETL(Extract-Transform-Load数据仓库技术)然后交给GraphX处理. Spark SQL的前身

javascript设计模式与开发实践阅读笔记(2)—— this,闭包与高阶函数

this this总是指向一个对象,有四种情况1. 作为对象的方法调用.2. 作为普通函数调用.3. 构造器调用.4. Function.prototype.call 或Function.prototype.apply 调用. 1. 作为对象的方法调用 当函数作为对象的方法被调用时,this 指向该对象: var obj = { a: 1, getA: function(){ alert ( this === obj ); // 输出:true alert ( this.a ); // 输出:

理解运用JS的闭包、高阶函数、柯里化

一.闭包 1. 闭包的概念 闭包与执行上下文.环境.作用域息息相关 执行上下文 执行上下文是用于跟踪运行时代码求值的一个规范设备,从逻辑上讲,执行上下文是用执行上下文栈(栈.调用栈)来维护的. 代码有几种类型:全局代码.函数代码.eval代码和模块代码:每种代码都是在其执行上下文中求值. 当函数被调用时,就创建了一个新的执行上下文,并被压到栈中 - 此时,它变成一个活动的执行上下文.当函数返回时,此上下文被从栈中弹出 function recursive(flag) { // Exit cond

PHP闭包和高阶函数

<?php function func($a, $b) { $line = function ($x) use ($a, $b) { return $a*$x + $b; }; return $line; } $line1 = func(1, 1); $line2 = func(3, 4); $x = 5; $y1 = $line1($x); $y2 = $line2($x); echo "x=$x ---> y1=$y1 , y2=$y2"; ?>

javascript设计模式与开发实践阅读笔记(3)——高阶函数的其他应用

高阶函数的其他应用 1.currying 函数柯里化,又称部分求值,一个currying 的函数首先会接受一些参数,接受了这些参数之后,该函数并不会立即求值,而是继续返回另外一个函数,刚才传入的参数在函数形成的闭包中被保存起来.待到函数被真正需要求值的时候,之前传入的所有参数都会被一次性用于求值. var cost = (function(){ var args = []; return function(){ if ( arguments.length === 0 ){ var money =

Python高阶函数-闭包

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回. 在这里我们首先回忆一下python代码运行的时候遇到函数是怎么做的. 从python解释器开始执行之后,就在内存中开辟了一个空间 每当遇到一个变量的时候,就把变量名和值之间的对应关系记录下来. 但是当遇到函数定义的时候解释器只是象征性的将函数名读入内存,表示知道这个函数的存在了,至于函数内部的变量和逻辑解释器根本不关心. 等执行到函数调用的时候,python解释器会再开辟一块内存来存储这个函数里的内容,这个时候,才关注函数里面有哪