ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript での関数のオーバーロードの説明

JavaScript での関数のオーバーロードの説明

不言
不言オリジナル
2018-07-13 16:38:411553ブラウズ

この記事では主に JavaScript の関数のオーバーロードの説明を紹介します。必要な友達に参考にしていただけるようにしました。

JavaScript のロードには実際の関数のオーバーロードはありません。

関数のオーバーロード

関数名は同じですが、関数のパラメータリストが異なり(パラメータの数やパラメータの型を含む)、パラメータの違いに応じて異なる操作が実行されます。

例を見てみましょう

function overload(a){
    console.log('一个参数')
}

function overload(a,b){
    console.log('两个参数')
}

// 在支持重载的编程语言中,比如 java
overload(1);         //一个参数
overload(1,2);    //两个参数


// 在 JavaScript 中
overload(1);         //两个参数
overload(1,2);    //两个参数

JavaScript では、同じ名前の 2 つの関数が同じスコープ内にある場合、後者の関数が前の関数を上書きするため、JavaScript ではオーバーロードの本当の意味はありません。

しかし、JavaScript でのオーバーロードの影響をシミュレートするさまざまな方法があります。

まず、arguments オブジェクトを通じて実装される最初のメソッドを見てみましょう。arguments オブジェクトは関数内の配列のようなオブジェクトで、関数呼び出し時に関数に渡されるすべてのパラメーターを格納します。

function overload () {
  if (arguments.length === 1) {
    console.log('一个参数')
  }
  if (arguments.length === 2) {
    console.log('两个参数')
  }
}

overload(1);      //一个参数
overload(1, 2);  //两个参数

この例は非常に単純で、引数オブジェクトの長さプロパティを判断してパラメータの数を決定し、どのような操作を実行します。

でも、パラメータが少ないときは大丈夫ですが、パラメータが増えるとif判定をたくさん書く必要があり面倒になります。

それでは、もう一度古典的な例を見てみましょう

この例を見る前に、まず、users オブジェクトがあり、いくつかの名前が users オブジェクトの value 属性に格納されているものを見てみましょう。

名前は以下のように 2 つの部分で構成され、スペースの左側が名、スペースの右側が姓です。

var users = {
  values: ["Dean Edwards", "Alex Russell", "Dean Tom"]
};

users オブジェクトに find メソッドを追加する必要があります。

パラメーターが渡されない場合は、users.values 全体が返されます。

パラメーターが渡される場合は、名が続きます。これにより、パラメータが一致する要素が返されます。

2 つのパラメータが渡された場合、両方に一致する姓と名が返されます。

この要件では、find メソッドはパラメーターの数に応じて異なる操作を実行する必要があります。次に、addMethod 関数を使用して、find メソッドを users オブジェクトに追加します。 users .values;  
当传一个参数时,就把 first-name 跟这个参数匹配的元素返回;    
当传两个参数时,则把 first-name 和 last-name 都匹配的返回。

这个需求中 find方法 需要根据参数的个数不同而执行不同的操作,下来我们通过一个 addMethod 函数,来在 users 对象中添加这个 find 方法。

function addMethod (object, name, fn) {
  // 先把原来的object[name] 方法,保存在old中
  var old = object[name];

  // 重新定义 object[name] 方法
  object[name] = function () {
    // 如果函数需要的参数 和 实际传入的参数 的个数相同,就直接调用fn
    if (fn.length === arguments.length) {
      return fn.apply(this, arguments);

      // 如果不相同,判断old 是不是函数,
      // 如果是就调用old,也就是刚才保存的 object[name] 方法
    } else if (typeof old === "function") {
      return old.apply(this, arguments);
    }
  }
}

addMethod 函数,它接收3个参数          
第一个:要绑定方法的对象,    
第二个:绑定的方法名称,      
第三个:需要绑定的方法

这个 addMethod 函数在判断参数个数的时候,除了用 arguments 对象,还用了函数的 length 属性。

函数的 length 属性,返回的是函数定义时形参的个数。

简单说 函数的 length 是,函数需要几个参数,而 arguments.length 是调用函数时,真的给了函数几个参数

function fn (a, b) {
  console.log(arguments.length)
}
console.log(fn.length);  // 2
fn('a');    // 1

下来我们来使用这个 addMethod 函数

// 不传参数时,返回整个values数组
function find0 () {
  return this.values;
}
// 传一个参数时,返回firstName匹配的数组元素
function find1 (firstName) {
  var ret = [];
  for (var i = 0; i <p>addMethod 函数是利用了闭包的特性,通过变量 old 将每个函数连接了起来,让所有的函数都留在内存中。</p><p>每调用一次 addMethod 函数,就会产生一个 old,形成一个闭包。<br>我们可以通过 <code>console.dir(users.find)</code> ,把 find 方法打印到控制台看看。</p><p><img src="https://img.php.cn//upload/image/139/643/301/1531471079834608.jpg" title="1531471079834608.jpg" alt="JavaScript での関数のオーバーロードの説明"></p><p>上面这个例子是  jQuery 之父 John Resig  写的,他在他的博客和他写的书 《secrets of the JavaScript ninja》第一版中都有提到过,在书中的第4章中也有讲解 Function overloading,文中的 addMethod 函数 就是书中的例子 4.15,感兴趣的朋友可以去看看。</p><p>上面的例子,本质都是在判断参数的个数,根据不同的个数,执行不同的操作,而下来举的例子是通过判断参数的类型,来执行不同的操作。</p><h3>我们看看 jQuery 中的 css( ) 方法。</h3><blockquote>css( ) 方法返回或设置匹配的元素的一个或多个样式属性。</blockquote><p><code>css(name|pro|[,val|fn])</code> </p><pre class="brush:php;toolbar:false">// name 表示属性名
// value 表示属性值
css: function( name, value ) {
    return access( this, function( elem, name, value ) {
        var styles, len,
            map = {},
            i = 0;

        // 判断属性名是不是数组
        // 是数组就遍历,调用jQuery.css 方法传入每个属性名,获取样式
        if ( Array.isArray( name ) ) {
            styles = getStyles( elem );
            len = name.length;

            for ( ; i  1 );
}
EdADDMETHOD 関数、3 つのパラメータを受け取ります 1 つ目: バインディング メソッドのオブジェクト、

2 つ目: バインディング メソッド名、3 つ目: バインドする必要があるメソッド JavaScript での関数のオーバーロードの説明

この addmetHod 関数は、この adDMethod 関数内にあります。パラメータの数には、引数オブジェクトの使用に加えて、関数の長さ属性も使用されます。


関数の長さ属性は、関数が定義されたときの仮パラメータの数を返します。

簡単に言えば、関数の長さは、関数がいくつかのパラメータを必要とすること、そして arguments.length は関数を呼び出すときに、実際に関数にいくつかのパラメータを与えることです

// 设置多个属性值
// 如果属性名(key)的类型是 object,就遍历这个对象
// 遍历一次就调用一次 access()方法,并传入这次的属性名和属性值
if ( jQuery.type( key ) === "object" ) {
    chainable = true;
    for ( i in key ) {
        jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
    }

// 设置一个值
} else if ( value !== undefined ) {
    ......
}

この addMethod 関数を使用しましょう

rrreee

addMethod 関数はクロージャの特性を利用し、変数 old を介して各関数を接続し、すべての関数がメモリ内に留まるようにします。

addMethod 関数が呼び出されるたびに、古いメソッドが生成され、クロージャが形成されます。
console.dir(users.find) を通じて find メソッドをコンソールに出力できます。 C 46129198-5B455 c7D6945FB_ARTICLEX [1] .jpg

上の例は、jQuery の父である John Resig によって書かれたものです。彼は自身のブログと、著書「JavaScript Ninja の秘密」の初版で言及しました。この本は、本書の第 4 章に掲載されています。この章では関数のオーバーロードについても説明しています。この記事の addMethod 関数については、この本の例 4.15 を参照してください。

上記の例は基本的に、パラメーターの数を判断し、異なる数値に基づいてさまざまな操作を実行することに関するものです。以下の例は、パラメーターの種類を判断することによってさまざまな操作を実行することについてのものです。 🎜🎜jQuery の css() メソッドを見てみましょう。 🎜🎜css( ) メソッドは、一致した要素の 1 つ以上のスタイル属性を返すか、設定します。 🎜🎜css(name|pro|[,val|fn]) 🎜🎜🎜🎜🎜 css() メソッドには 5 つのパラメーターの状況があり、そのうち 3 つは 1 つのパラメーターであることがわかります。 other どちらも 2 つのパラメータです。 🎜パラメータが1つの場合、パラメータの型が文字列または配列の場合は属性値を取得し、パラメータがオブジェクトの場合は属性値を設定します。 🎜🎜jQueryのcss()メソッドはパラメータの型を判断してどのような操作を実行するかを決定します。 🎜🎜jQuery 3.3.1 のソース コードを見てみましょう🎜rrreee🎜css( ) メソッドは 3 つのメソッドに依存しています: 🎜🎜1. このメソッドは 1 つ以上の属性値を取得または設定できます。 🎜🎜jQuery.access() メソッドにはそのようなコードが含まれています🎜rrreee🎜これは、css() メソッドが最初のパラメーターが文字列であるかオブジェクトであるかを判断するのに役立つメソッドです。 🎜
2. jQuery.style() メソッド: DOM ノードのスタイル属性を読み取るか設定します

css() メソッドでは、2 番目のパラメーターが渡される場合、つまり、設定する属性値がある場合、 jQuery.style() メソッドを呼び出してスタイルを設定します

3. jQuery.css(): DOM 要素の DOM スタイル値を読み取ります

ここでの jQuery.css() は jQuery.extend( ) 添加的方法,而我们最开始提到的 css( )方法,是通过 jQuery.fn.extend( ) によって追加されたメソッドです。同じ方法ではありません。

jQuery.extend( ) と jQuery.fn.extend( ) の違い

jQuery.extend( ) は、jQuery クラスにクラスメソッド (静的メソッド) を追加することです。これは、jQuery を通じて呼び出す必要があります。 class ($.xxx Call を直接使用);

jQuery.fn.extend() は jQuery クラスにメンバー (インスタンス メソッド) を追加し、すべての jQuery インスタンスを直接呼び出すことができます ($().xxx を使用する必要があります)。電話)。

オーバーロードの利点

オーバーロードは実際に、類似した機能を持つ複数の関数を 1 つの関数にマージし、関数名を再利用します。
jQuery の css() メソッドがオーバーロードを使用しない場合、関数を完成させるには 5 つの異なる関数が必要になります。その場合、5 つの異なる関数名と、各関数に対応するパラメーターの数を覚えておく必要があります。もっと面倒です。

まとめ

JavaScript には本当の意味でのオーバーロードはありませんが、JavaScript ではオーバーロードの影響が非常に一般的で、たとえば、配列の splice() メソッドでは、1 つのパラメーターが削除され、2 つのパラメーターで一部が削除されることがあります。新しい要素を追加する前に 3 つのパラメータを削除できます。
もう 1 つの例は、parseInt() メソッドです。パラメータが渡されると、16 進解析を使用するか 10 進解析を使用するかが判断されます。2 つのパラメータが渡された場合、2 番目のパラメータが数値の基数として使用されます。解析中。

この記事で説明されているオーバーロード効果を実現する方法は、基本的にパラメーターの数を判断するかパラメーターの種類を判断するかに基づいており、操作はさまざまなパラメーターに基づいて決定されます。

オーバーロードは非常に便利ですが、無関係な関数を 1 つの関数に結合しないでください。あまり意味がありません。

上記がこの記事の全内容です。その他の関連コンテンツについては、PHP 中国語 Web サイトをご覧ください。

関連する推奨事項:

js でのイベントバブリングとイベントキャプチャの分析

Ajax がクロスドメインアクセスを実装する方法の紹介

以上がJavaScript での関数のオーバーロードの説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。