Javascriptg高级函数

Javascript高级函数

  • 惰性载入函数
  • 函数柯里化
  • 级联函数

这并不全面,只是几个主要的。

惰性载入函数

  惰性载入表示函数执行的分支只会在函数第一次掉用的时候执行,在第一次调用过程中,该函数会被覆盖为另一个按照合适方式执行的函数,这样任何对原函数的调用就不用再经过执行的分支了。

  写一个函数用来创建XmlHttpRequest对象,浏览器兼容性原因,写出的代码通过大量if判断或者try,catch语句将函数引导到正确代码处。

代码示例:

function createXHR(){
    var xhr = null;
    try {
        // Firefox, Opera 8.0+, Safari,IE7+
        xhr = new XMLHttpRequest();
    }
    catch (e) {
        // Internet Explorer
        try {
            xhr = new ActiveXObject("Msxml2.XMLHTTP");
        }
        catch (e) {
            try {
                xhr = new ActiveXObject("Microsoft.XMLHTTP");
            }
            catch (e) {
                xhr = null;
            }
        }
    }
    return xhr;
}

  每次调用这个函数的时候,都要先进行浏览器能力检查,首先检查浏览器是否支持内置的XMLHyypRequest对象,如果不支持然后检查各版本基于ActiveX的XMLHttpRequest,每次调用该函数都是这样,其实当第一次执行完后,如果浏览器支持某个特定XMLHttpRequest对象,那么下次执行的时候这种支持性并不会改变,没必要再进行一边检测,即使只有一个if语句,执行也肯定比没有要慢,如果我们可以让if语句不必每次执行,那么就可以在频繁调用的情况下提高执行速度。并且如果在多次createXHR后没有处理好,还会非常容易造成内存泄漏。解决方案就是惰性载入。在已经判断出当前浏览器是什么的时候,就让createXHR == XHR;

function createXHR(){
  var xhr=null;  if(typeof XMLHttpRequest !=‘undefined‘){
     xhr = new XMLHttpRequest();
      createXHR=function(){
        return new XMLHttpRequest();
      }
   }else{
     try {
        xhr = new ActiveXObject("Msxml2.XMLHTTP");
         createXHR=function(){
           return new ActiveXObject("Msxml2.XMLHTTP");
         }
      }
      catch (e) {
        try {
           xhr = new ActiveXObject("Microsoft.XMLHTTP");
            createXHR=function(){
              return new ActiveXObject("Microsoft.XMLHTTP");
            }
         }
         catch (e) {
           createXHR=function(){
            return null;
            }
         }
      }
   }
                return xhr;
}

  在这个惰性载入的createXHR中第一次执行的时候每个分支都会为createXHR重新赋值,覆盖原函数,返回xhr对象,而第二次执行的时候就会直接调用重写后的函数,这样就不必执行每个分支重新做检测了。

函数柯里化

  在计算机科学中,柯里化(英语:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。

  说起函数柯里化,我理解起来确实费了很大一波力,首先对于代码中的很多部分都不理解,比如slice、call()、apply()【日后会写这三个】。理解了这些之后自然能够看懂柯里化的通用实现:

代码示例:

function currying(fn) {
    var args = Array.prototype.slice.call(arguments, 1);
    return function () {
        var innerArgs = Array.prototype.slice.call(arguments);
        var finalArgs = args.concat(innerArgs);
        console.log (finalArgs);
        return fn.apply(this,finalArgs);
    };
}
    1. 提高适用性

      代码示例:

      function square(i) {
          return i * i;
      }
      
      function dubble(i) {
          return i *= 2;
      }
      
      function map(handeler, list) {
          return list.map(handeler);
      }
      
      // 数组的每一项平方
      map(square, [1, 2, 3, 4, 5]);
      map(square, [6, 7, 8, 9, 10]);
      map(square, [10, 20, 30, 40, 50]);
      // ......
      
      // 数组的每一项加倍
      map(dubble, [1, 2, 3, 4, 5]);
      map(dubble, [6, 7, 8, 9, 10]);
      map(dubble, [10, 20, 30, 40, 50]);
      

      例子中,创建了一个map通用函数,用于适应不同的应用场景。。同时,例子中重复传入了相同的处理函数:square和dubble。

      应用中这种需要处理的东西会更多。通用性的增强必然带来适用性的减弱。但是,我们依然可以在中间找到一种平衡。

      看下面,我们利用柯里化改造一下:

      代码示例:

      function square(i) {
          return i * i;
      }
      
      function dubble(i) {
          return i *= 2;
      }
      
      function map(handeler, list) {
          return list.map(handeler);
      }
      
      var mapSQ = currying(map, square);
      mapSQ([1, 2, 3, 4, 5]);
      mapSQ([6, 7, 8, 9, 10]);
      mapSQ([10, 20, 30, 40, 50]);
      // ......
      
      var mapDB = currying(map, dubble);
      mapDB([1, 2, 3, 4, 5]);
      mapDB([6, 7, 8, 9, 10]);
      mapDB([10, 20, 30, 40, 50]);
      // ......
      

      柯里化降低通用性,提高适用性。  

    2. 延迟执行

      不断的柯里化,累计传入的参数,最后执行。

      代码示例:

      var add = function() {
          var _this = this,
          _args = arguments
          return function() {
              if (!arguments.length) {
                  var sum = 0;
                  for (var i = 0,c; c = _args[i++];) sum += c;
                  return sum;
              } else {
                  Array.prototype.push.apply(_args, arguments)             return arguments.callee;
              }
          }
      }
      add(1)(2)(3)(4)();//10
      

      柯里化:

      var curry = function(fn) {
          var _args = []
          return function cb() {
              if (arguments.length == 0) {
                  return fn.apply(this, _args)
              }
              Array.prototype.push.apply(_args, arguments);
              return cb;
          }
      }
      

        

    3. 固定易变因素

      柯里化特性决定了它可以提前把易变因素,传参固定下来,生成一个更明确的应用函数。最典型的代表应用,是bind函数用以固定this这个易变对象。

      Function.prototype.bind = function(context) {
          var _this = this,
          _args = Array.prototype.slice.call(arguments, 1);
          return function() {
              return _this.apply(context, _args.concat(Array.prototype.slice.call(arguments)))
          }
      }
      

但其实我还是没有那么透彻的理解函数柯里化,应该等到其他的知识掌握的更加熟练,理解起来也才会更加容易吧

级联函数

  级联函数也叫链式函数,方法链一般适合对一个对象进行连续操作(集中在一句代码),一定程度上把相关的属性都连到一起,减少代码量,缺点是它占用了函数的返回值。

function myclassA(){
 this.name="";
 this.age="";
 this.sex="";
}
myclassA.prototype={
 setname:function(){
  this.name="katherine";
  return this;
 },
 setage:function(){
  this.age="22";
  return this;
 },
 setsex:function(){
  this.sex=‘girl‘;
  return this;
 }
}
var me =new myclassA();
console.log(me.setname().setage().setsex());

// myclassA {name: "katherine", age: "22", sex: "girl"}

  这一篇整整弄了两天才弄完,但是还是有些搞不懂函数柯里化,我想只能在日后的开发中,慢慢接触项目来解锁理解了【摊手】

  

时间: 2024-08-29 18:37:55

Javascriptg高级函数的相关文章

高级函数

高级函数 安全的类型检测 js内置的类型检测并非完全可靠,typeof操作符难以判断某个值是否为函数 instanceof在多个frame的情况下,会出现问题. 例如:var isArray = value instance of Array ; 会由于存在多个window,而value与Array不属于同个window的情况而导致出错 对于这样的问题,最好的解决方法是通过调用Object的toString方法,例如: 1 function isArray(){ 2 return Object.

什么是回调或高级函数?

http://blog.csdn.net/luoweifu/article/details/41466537    在JavaScrip中,function是内置的类对象,也就是说它是一种类型的对象,可以和其它String.Array.Number.Object类的对象一样用于内置对象的管理.因为function实际上是一种对象,它可以“存储在变量中,通过参数传递给(别一个)函数(function),在函数内部创建,从函数中返回结果值”. 因为function是内置对象,我们可以将它作为参数传递

第五天(全局变量,局部变量,高级函数)

在python中,没有缩进的变量为全局变量,推荐全部用大写字母. NAME = "aitg" def mz(): global NAME print(NAME) mz() 在代码块内部的变量为局部变量. def mz(): name = "aitg" print(name) mz() 局部变量还可以使用global方法指定为全局变量 NAME = "码农也疯狂" def mz(): global NAME NAME = "aitg&qu

python局部变量、高级函数、匿名函数、嵌套函数、装饰器

1.局部变量 在函数内部,可以用Global,显式的声明为全局变量.这种方式永远不要这么用. Ctrl+?多行注释i 2.高级函数 把函数名当做参数,传给函数 def add(a,b,f): return f(a)+f(b) res = add(3,-6,abs) abs是内置函数 def bar(): print("in the bar") def test1(func): 首先看第一个例子:def bar(): print("in the bar") def t

第33天pytho学习装饰器:高级函数部分演示

#迭代器:把列表变为迭代器# l=[1,3]# l1=iter(l)#转换成迭代器# print(l1)# print(next(l1))#——————转换成迭代器把第一个值取出来 #装饰器:本质就是函数:功能:为其他函数添加附加功能#原则:1.不修改被修饰函数的源代码 2.不修改被修饰函数的调用方式 #统计函数的时间# import time#添加个时间模块# def test(l):# start_time=time.time()#开始时间# res=0# for i in l:# time

numpy高级函数:where与extract

numpy高级函数:where与extract 1.numpy.where()函数,此函数返回数组中满足某个条件的元素的索引: import numpy as np x = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) print("x") print(x) y=np.where(x>5) print(y) print(x[y]) 2.numpy.extract()函数,和where函数有一点相,不过extract函数是返回满足条件的元素

一篇文章把你带入到JavaScript中的闭包与高级函数

在JavaScript中,函数是一等公民.JavaScript是一门面向对象的编程语言,但是同时也有很多函数式编程的特性,如Lambda表达式,闭包,高阶函数等,函数式编程时一种编程范式. function dada() { var a = 1; var b = function() { console.log(a); } return b // b 就是一个闭包函数,因为它能访问dada函数的作用域 } JavaScript的函数也是对象,可以有属性,可以赋值给一个变量,可以放在数组里作为元素

JavaScript系列:高级函数篇

前言: 本篇主要是介绍 JavaScript使用函数的高级方法,函数是JavaSCript中最有趣的部分,利用Function特性可以编写出很多非常有意思的代码,本篇主要包括:函数回调,高阶函数以及函数柯里化. 1.   函数回调 对于异步编程JavaScript API如SetTimeout或者JQuery的$.ajax又或者越来越火的Node.js编程,在事件循环上都是非阻塞的,意思就是,当你使用异步非阻塞API的使用,调用在回调函数执行之前立即返回,而这些回调在不久之后执行. 1 setT

python Day3 集合 文件处理 函数 字符编码 递归 高级函数

集合 集合是一个无序的,不重复的数据组合,它的主要作用如下: 去重,把一个列表变成集合,就自动去重了 关系测试,测试两组数据之前的交集.差集.并集等关系 常用操作 s = set([3,5,9,10]) #创建一个数值集合 t = set("Hello") #创建一个唯一字符的集合 a = t | s # t 和 s的并集 b = t & s # t 和 s的交集 c = t – s # 求差集(项在t中,但不在s中) d = t ^ s # 对称差集(项在t或s中,但不会同时