javascript高级知识点——函数的长度

代码信息来自于http://ejohn.org/apps/learn/。

函数的长度属性如何工作?

function makeNinja(name){}
function makeSamurai(name, rank){}
console.log( makeNinja.length == 1, "只定义了一个形参" );
console.log( makeSamurai.length == 2, "定义了两个形参" );

很清楚,函数的长度就是定义形参的个数。

我们可以利用这一点写重载函数

function addMethod(object, name, fn){
  // 存储对过去方法的引用
  var old = object[ name ]; 

  // 重写新的方法
  object[ name ] = function(){
    // 核对定义形参的个数,
    // 与我们接受接收参数的个数
    if ( fn.length == arguments.length )
      // 如果匹配运行这个函数
      return fn.apply( this, arguments ); 

    // 否则调用过去的方法
    else if ( typeof old === "function" )
      return old.apply( this, arguments );
  };
}

来看一看重载函数的运用

function addMethod(object, name, fn){
  // 存储对过去方法的引用
  var old = object[ name ]; 

  // 重写新的方法
  object[ name ] = function(){
    // 核对定义形参的个数,
    // 与我们接受接收参数的个数
    if ( fn.length == arguments.length )
      // 如果匹配运行这个函数
      return fn.apply( this, arguments ); 

    // 否则调用过去的方法
    else if ( typeof old === "function" )
      return old.apply( this, arguments );
  };
}

function Ninjas(){
  var ninjas = [ "Dean Edwards", "Sam Stephenson", "Alex Russell" ];
  addMethod(this, "find", function(){
    return ninjas;
  });
  addMethod(this, "find", function(name){
    var ret = [];
    for ( var i = 0; i < ninjas.length; i++ )
      if ( ninjas[i].indexOf(name) == 0 )
        ret.push( ninjas[i] );
    return ret;
  });
  addMethod(this, "find", function(first, last){
    var ret = [];
    for ( var i = 0; i < ninjas.length; i++ )
      if ( ninjas[i] == (first + " " + last) )
        ret.push( ninjas[i] );
    return ret;
  });
} 

var ninjas = new Ninjas();
console.log( ninjas.find());
console.log( ninjas.find("Sam"));
console.log( ninjas.find("Dean", "Edwards"));
console.log( ninjas.find("Alex", "X", "Russell"));

实例化ninja时,向ninja执行了4次添加方法,每次都覆盖在find属性上,根据闭包的作用域链,新的方法仍然可以引用addMethod里old,old保存的是上一个方法。

最后的find就是判断参数,与形参数量是否相同,是就执行,不是就调用old的方法。如此反复。

等同于以下代码

var ninjas = {
    find: function(){
        var ninjas = [ "Dean Edwards", "Sam Stephenson", "Alex Russell"]
        var old = function(){
            var ninjas = [ "Dean Edwards", "Sam Stephenson", "Alex Russell"]
            var old = function(){
                var ninjas = [ "Dean Edwards", "Sam Stephenson", "Alex Russell"]
                var old;
                var fn =   function(){
                    return ninjas;
                  }
                if ( fn.length == arguments.length ) {
                  return fn.apply( this, arguments );
                }else if ( typeof old === "function" ) {
                  return old.apply( this, arguments );
                }
            };
            var fn =  function(name){
                var ret = [];
                for ( var i = 0; i < ninjas.length; i++ )
                  if ( ninjas[i].indexOf(name) == 0 )
                    ret.push( ninjas[i] );
                return ret;
              }
            if ( fn.length == arguments.length ) {
              return fn.apply( this, arguments );
            }else if ( typeof old === "function" ) {
              return old.apply( this, arguments );
            }
        }
        var fn =  function(first, last){
            var ret = [];
            for ( var i = 0; i < ninjas.length; i++ )
              if ( ninjas[i] == (first + " " + last) )
                ret.push( ninjas[i] );
            return ret;
        }
        if ( fn.length == arguments.length ) {
          return fn.apply( this, arguments );
        }else if ( typeof old === "function" ) {
          return old.apply( this, arguments );
        }
    },
}
console.log( ninjas.find());
console.log( ninjas.find("Sam"));
console.log( ninjas.find("Dean", "Edwards"));
console.log( ninjas.find("Alex", "X", "Russell"));
时间: 2024-10-25 15:57:42

javascript高级知识点——函数的长度的相关文章

javascript高级知识点——函数原型

代码信息来自于http://ejohn.org/apps/learn/. 向函数的原型中添加方法 function Ninja(){} Ninja.prototype.swingSword = function(){ return true; }; var ninjaB = new Ninja(); console.log( ninjaB.swingSword(), "Method exists and is callable." ); 通过实例化对象可以访问,因为构造函数实例化的对象

JavaScript的最大函数参数长度和最大栈深度检测

也许一般代码不会触及最大参数长度和最大栈深度,但某些特殊场合,检测这两个参数还是有必要的 例如:用递归计算斐波那契数列的第n个值,不了解最大栈深度,难免显得肤浅 又例如:将一串charCode转成String,不了解最大参数长度,采用字符串拼接的方式,效率提不上,特别是在串较长的情况下 function getMaximumSupportedArgumentsLength(){ var args={length:0}; function noop(){} function test(n){ ar

1、JavaScript高级之函数作用域链

作用域链: JavaScript的每个函数function都有自己的作用域,使用Active Object(简称AO)活动对象来保存,在相互嵌套的函数中形成了作用域链,如图: 作用域链就是从里到外的AO链 变量的寻找: 函数fn3中使用的变量,如在fn3作用域内寻找不到,则往外层fn2作用域寻找,以此类推,直到全局对象window 代码演示: var c = 5; function t1(){ var d = 6; function t2(){ var e = 7; var d = 3;//如果

JavaScript高级-----8.函数进阶(2)

3. 严格模式 3.1 概述 3.2 开启严格模式 1. 为脚本开启严格模式 (1) (2) <body> <!-- 为整个脚本(script标签)开启严格模式 --> <!-- (1) --> <script> 'use strict'; //单引号双引号都可以 // 下面的js 代码就会按照严格模式执行代码 </script> <!-- (2) --> <script> (function() { 'use stric

Javascript高级程序设计——函数内部属性与函数属性

函数内部属性 函数内部有两个特殊的属性arguments和this.其中,arguments是类数组对象,包含传入函数中的所有值,这个arguments还有一个属性:callee,这个属性是一个指针,指向拥有arguments的函数.而this据以引用的是函数执行环境对象. function fib(n){ if(n = 1){ return 1; }else{ return n * arguments.callee(n - 1); } } //这里利用函数内arguments的callees属

JavaScript高级程序设计: 函数表达式

闭包 闭包是指有权访问另一个函数函数作用域中的变量(内部变量)的函数. function createComparsionFunction( propertyName ){ return function( object1 , object2 ){ var value1 = object1[ propertyName ]; var value2 = object2[ propertyName ]; if( value1 < value2 ){ return -1; } else if( valu

javascript高级知识点——指定上下文实现

代码信息来自于http://ejohn.org/apps/learn/. 当我们将一个对象的点击事件绑定到一个事件触发元素时会发生什么? <ul id="results"> </ul> <script> var Button = { click: function(){ this.clicked = true; } }; var elem = document.createElement("li"); elem.innerHTML

javascript高级知识点——继承

代码信息来自于http://ejohn.org/apps/learn/. 继承是如何工作的 function Person(){} function Ninja(){} Ninja.prototype = new Person(); var ninja = new Ninja(); console.log( ninja instanceof Ninja, "ninja自动接收Ninja.prototype里的属性" ); console.log( ninja instanceof Pe

javascript高级知识点——临时作用域

代码信息来自于http://ejohn.org/apps/learn/. 自执行,临时,函数 (function(){ var count = 0; })(); 这是一个简单的自执行匿名函数. 做一个点击计数 document.addEventListener("click", (function(){ var numClicks = 0; return function(){ alert( ++numClicks ); }; })(), false); 关键代码是,自执行匿名函数,返