Function 函数

重要通知

类目简介

基本概况

  • function、new function与new Function的区别
# new function都发生了什么?
new的实例绑定了new 的对象的this
new 的实例继承了new的原型链


# function:声明一个函数
function test() {console.log(1)}; 

# new function:实例化一个函数对象
var obj = new function(a) {this.a = 1;};
console.log(obj.a);  $->1

# new Function:函数构造器,将字符片段转换为可执行代码
  let evalCode = "console.log('hello')";
  (new Function(evalCode))();
> 语法
  new Function([args...], 函数体)
  let sum = new Function('a', 'b', 'return a + b');
  alert(sum(1, 2));

  • Function.length

module.exports = async function() {
  console.log("|-----" + "module" + "-----FILE_URL: " + __filename);

  //业务模型
  await init();

}

async function init() {
  function Person(sex, age) {
    console.log('实际参数: ' + arguments.length);  //1
    //返回声明函数的形式参数长度
    console.log('形式参数: ' + Person.length);  //2
  }
  Person('男');
}

  • Function.name
module.exports = async function() {
  console.log("|-----" + "module" + "-----FILE_URL: " + __filename);

  //业务模型
  await init();

}

async function init() {
  function Person() {
    //返回函数实例的名称
    console.log(Person.name);
  }
  Person();

  //使用new Function()或Function()创建的对象及其名称为anonymous
  console.log((new Function).name);  //anonymous
}
function Parent() {
  this.name = '父类';
}

function Child() {
  this.name = '子类';
}

promisify

/**
 一、实现一个promisify函数,可以回调一下两个函数printDail与printSuccess,例如:
 promisify(printDail)('printDail').then((res)=> {console.log(res);}).catch((err)=> {console.log(err);});
 promisify(printSuccess)('printSuccess').then((res)=> {console.log(res);}).catch((err)=> {console.log(err);});
 */
function promisify(fn) {
  return function() {
    let args = Array.prototype.slice.call(arguments);
    return new Promise(function (resolve, reject) {
      args.push(function (err, result) {
          if (err) {
            reject(err);
          }
          resolve(result);
      });
      fn.apply(null, args);
    });
  }
}

//函数一:printDail
function printDail(name, callback) {
  console.log("name: " + name);
  callback(1);
}
//函数二:printSuccess
function printSuccess(name, callback) {
  console.log("name: " + name);
  callback(0);
}

//实现条件:promisify可以调用以上两个函数
promisify(printDail)('printDail').then((res)=> {console.log(res);}).catch((err)=> {console.log(err);});
promisify(printSuccess)('printSuccess').then((res)=> {console.log(res);}).catch((err)=> {console.log(err);});

属性

Function.arguments:[已废弃] 代表传入函数的实参,它是一个类数组对象。 Function.caller:返回调用指定函数的函数,判断函数调用情况,如果函数在顶层调用,返回null,否则返回调用该函数当前函数的Function对象的引用 [该特性是非标准的,请尽量不要在生产环境中使用它] Function.length:指明函数的形参个数。 Function.name:返回函数实例的名称。

方法

Function.prototype.apply():调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数。 Function.prototype.bind():创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。 Function.prototype.call():使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。 Function.prototype.toString():返回一个表示当前函数源代码的字符串。

代码示例

  function Run(a, b) {
    return a + b;
  }
  console.log(Run.toString()); // function Run(a, b) { return a + b; }  

封闭函数 | IIFE (立即执行函数表达式)

  function say(txt) {
    console.log(txt);
  }
  function executeFn(fnName, txt) {
    fnName(txt);
  }
  executeFn(say, 'Hello World');

  // 整合
  (function(fnName, txt) {
    fnName(txt);
  })(function(txt) {
    console.log(txt);
  }, 'Hello World');

Arguments函数参数

形式参数与实际参数

  function Person(sex, age, height, weight) {
    console.log(arguments);  //[Arguments] { '0': '女', '1': 27 }
    console.log('实际参数: ' + arguments.length);  //2
    console.log('形式参数: ' + arguments.callee.length);  //4
  }
  Person('女', 27);
  
  function Person(sex, age) {
    console.log('实际参数: ' + arguments.length);  //1
    console.log('形式参数: ' + Person.length);  //2
  }
  Person('男');

递归调用

使用函数名的递归调用

  function filter(x) {
    if (x % 2 == 0) {
      console.log(x);
    } 
    if (x > 0) {
      return filter(x - 1);
    }
  }
  filter(6);   //6 4 2 0

arguments.callee:当前正在执行的函数 | 在ES5中舍弃与禁用

  function filter(x) {
    console.log(arguments.callee.length);  //形式参数长度 
    if (x % 2 == 0) {
      console.log(x);
    } 
    if (x > 0) {
      arguments.callee(x-1);
    }
  }
  filter(6);   //6 4 2 0

encoded

module.exports = async function() {
  console.log("|-----" + "String" + "-----FILE_URL: " + __filename);

  //业务模型
  await init();

}

async function init() {
  Escape();
  EncodeURI();
  EncodeURIComponent();

}


/**
 * 编码语法
 * escape:较好
 * encodeURI:编码比escape差
 * encodeURIComponent:编码最好
 */
async function Escape() {
  let conent = "|-a@-0-https://-*-www.-b_c-+\/--!#?^&$~{}[],--()=;;。,‘’--、“”-1-\'--";
  let edit = escape(conent);

  console.log(edit);
  //%7C-a@-0-https%3A//-*-www.-b_c-+/--%21%23%3F%5E%26%24%7E%7B%7D%5B%5D%2C--%28%29%3D%3B%uFF1B%u3002%uFF0C%u2018%u2019--%u3001%u201C%u201D-1-%27--
  //console.log(unescape(edit));
}

async function EncodeURI() {
  let conent = "|-a@-0-https://-*-www.-b_c-+\/--!#?^&$~{}[],--()=;;。,‘’--、“”-1-\'--";
  let edit = encodeURI(conent);

  console.log(edit);
  //%7C-a@-0-https://-*-www.-b_c-+/--!#?%5E&$~%7B%7D%5B%5D,--()=;%EF%BC%9B%E3%80%82%EF%BC%8C%E2%80%98%E2%80%99--%E3%80%81%E2%80%9C%E2%80%9D-1-'--
  //console.log(decodeURI(edit));
}

async function EncodeURIComponent() {
  let conent = "|-a@-0-https://-*-www.-b_c-+\/--!#?^&$~{}[],--()=;;。,‘’--、“”-1-\'--";
  let edit = encodeURIComponent(conent);

  console.log(edit);
  //%7C-a%40-0-https%3A%2F%2F-*-www.-b_c-%2B%2F--!%23%3F%5E%26%24~%7B%7D%5B%5D%2C--()%3D%3B%EF%BC%9B%E3%80%82%EF%BC%8C%E2%80%98%E2%80%99--%E3%80%81%E2%80%9C%E2%80%9D-1-'--
  //console.log(decodeURIComponent(edit));
}

currying

/**
 * lodash
 * https://lodash.com/
 * https://github.com/lodash/lodash/tree/4.3.0-npm-packages
 */
module.exports = async function() {
  console.log("|-----" + "柯里化函数" + "-----FILE_URL: " + __filename);

  //业务模型
  await init();

}

async function init() {
  Case();
  //Example();
  //Grammar();

}

async function Case() {
  
}

async function Example() {
  function curring() {
    let value = 0;
    if (!arguments.length) {
      value = 0;
    } else {
      let value = 0;
      Array.from(arguments).map((dx)=> {
        value += dx;
      });
    }
    return value;

    //柯里化函数

  }

  console.log(curring(0));
}

/**
 * 柯里化函数: 把接受多个参数的函数转换成接受一个单一参数的函数
 * 减少代码冗余, 增强代码可读性
 * 参数复用
 * 延迟执行
 * 函数式编程中,作为compose, functor, monad 等实现的基础
 * 
 */
async function Grammar() {
  function curring(f) {
    var len = f.length;
      
    return function t() {
      var innerLength = arguments.length,
        args = Array.prototype.slice.call(arguments);
        
      if (innerLength >= len) {   // 递归出口,f.length
         return f.apply(undefined, args)
      }
      return function() {
        var innerArgs = Array.prototype.slice.call(arguments),
          allArgs = args.concat(innerArgs);
          
        return t.apply(undefined, allArgs)
      }
    }
  } 
  //功能体
  function add(a, b) {
    return a + b;
  }
  let calcu = curring(add)(1)(2);
  console.log(calcu);
}



/**
 * 反柯里化
 * 
 */


arguments

module.exports = function(args0, args1, args2) {
  //[Arguments] {}
  
  console.log(arguments); 
  console.log('arguments.length: ' + arguments.length);
  console.log(arguments.constructor === Object);  //true
  console.log('arguments[0]: ' + arguments[0]);

  //在严格模式下,第5版 ECMAScript (ES5) 禁止使用 arguments.callee()
  console.log(arguments.callee);
  console.log(arguments.callee.length);  //形式参数

  function Person(sex, age, height, weight) {
    console.log(arguments);  //[Arguments] { '0': '女', '1': 27 }
    console.log('实际参数: ' + arguments.length);  //2
    console.log('形式参数: ' + arguments.callee.length);  //4
  }
  Person('女', 27);

  //arguments.callee
  function calculate(count) {
    console.log(count);
    if (count > 0) {
      arguments.callee(count - 1);
    }
  }
  //calculate(10);  //10 9 8 7 6 5 4 3 2 1 


}

API

属性与方法

Function.prototype.constructor Function.prototype.hasOwnProperty Function.prototype.isPrototypeOf Function.prototype.propertyIsEnumerable Function.prototype.toLocaleString Function.prototype.toString Function.prototype.valueOf

Function.prototype.apply Function.prototype.arguments Function.prototype.bind Function.prototype.call Function.prototype.caller Function.prototype.length Function.prototype.name

匿名函数 anonymous


/**
 * 匿名函数 | 自调用(执行)
 */
(function() {
  'use strict';
  
  //console.log(0);
})();

!function() {
  'use strict';

  //console.log(0);
}();

(function() {
  'use strict';

  //console.log(0);
}());


(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  typeof define === 'function' && define.amd ? define(factory) :
  (global = global || self, global.Vue = factory());
}(this, function () { 'use strict';}));



(function(global, factory) {
  factory();
})(this, function() {
  //console.log(this);  //Window {parent: Window, postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, …}
});

(function(global, factory) {
  factory();
}(this, function() {
  'use strict';
  //module
  //console.log(this);  //undefined
}));

!function(global, factory) {
  factory();
}(this, function() {
  'use strict';
  //console.log(this);  //undefined
});

Last Updated:
Contributors: 709992523