ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript 関数バインディングの使用状況分析

JavaScript 関数バインディングの使用状況分析

小云云
小云云オリジナル
2018-01-19 10:50:411663ブラウズ

この記事では、主に JavaScript 関数バインディングの使用法を紹介し、JavaScript 関数バインディングの原理、実装方法、および関連する操作テクニックを例の形で分析します。必要な友人が参考になれば幸いです。

Perface

このページと、1、2、3 などのクリックなどのいくつかの操作を実装するよう求められた場合、入力テキストに表示されます。削除機能は、ただのシミュレーションですので、電話してそのままにしてください。私がそれを始めたばかりなら、次のようにします:

1. CSS と HTML を使用してインターフェイスをレイアウトします

2. JavaScript イベント委任を使用して、ボタンの親ノードのクリック イベントを監視します

オブジェクト指向を使って考えたいことはありますか?私は Ext でそれを行ったので、カプセル化に非常に役立ちました。 Ext を使用したことがない人の中には、以下に投稿したコードをよく理解できない人もいるかもしれませんが、わかりやすく説明できるよう最善を尽くします。

説明


ContactTelPanel =Ext.extend(Ext.Panel, {
  //构造方法
  constructor : function(config) {
    Ext.apply(this, config);//直接把config对象的属性全复制到this对象中
    Parent = this.parent;
    var me = this;
    ContactTelPanel.superclass.constructor.call(this, {//用ContactTelPanel的父类也就是Ext.Panel的构造函数
      autoScroll : true,
      title : "拨打电话",//设置title,跟这篇文章的主体没关系,不要管他
      id : "contacttelpanel",
      bodyStyle : "padding: 30px 300px;",
      defaults : {//可以为该对象(ContactTelPanel)包含的组件(也就是在items配置选项)设置一些相同属性
        layout : "column",
        defaults : {
          xtype : "button",
          width : 50,
          height : 25,
          style : "margin:4px 15px",
          handler : this.press //为每个按钮都添加一个click的事件
        },
        bodyBorder : false
      },
      items : [ {//textfield组件
        height : 30,
        width : 250,
        xtype : "textfield",
        id : "tf",
        style : "margin-bottom:10px"
      }, {// 没有xtype就是默认为panel,下面也是,不然就不要纠结了,直接在这里想象成第一行按钮1、按钮2、按钮3
        items : [ {
          text : "1"
        }, {
          text : "2"
        }, {
          text : "3"
        } ]
      }, {// 这里是按钮4、按钮5、按钮6
        items : [ {
          text : "4"
        }, {
          text : "5"
        }, {
          text : "6"
        } ]
      }, {// 这里是按钮7、按钮8、按钮9 下同
        items : [ {
          text : "7"
        }, {
          text : "8"
        }, {
          text : "9"
        } ]
      }, {
        items : [ {
          text : "*"
        }, {
          text : "0"
        }, {
          text : "#"
        } ]
      }, {
        items : [ {
          text : "拨打",
        }, {
          text : "删除",
        } ]
      } ]
    });
  },
  press : function() {
    var text = this.text, textfield = Ext.getDom("tf");
    if (/[0-9*#]/.test(text)) {//在textfield中显示所点击按钮的数字
      textfield.value += text;
    } else if (this.text == "删除") {//删除功能
      textfield.value = textfield.value.slice(0, -1);
    } else if (this.text == "拨打") {//这个先不要管他
      Tel.telcall(textfield.value);
    }
  }
});

注: 実際、上記のことから、ContactTelPanel が Ext.Panel を継承しており、このパネルには多数のキーがあり、各キーがクリック イベントをリッスンしていることがわかります。各ボタンがクリックイベントをリッスンするため、効率に大きく影響するため、ここではイベントデリゲーションを使用する必要があると感じています。イベント委任を使用すると、親ノードのクリック イベントをリッスンするだけで、ターゲット オブジェクトを決定し、イベント フローに基づいて操作できます。この記事の焦点は、引き続き listen イベントの handler: this.press のコードにあります。私が遭遇した問題は、プレス機能でこの ContactTelPanel クラスの一部の属性を使用する必要がある場合はどうすればよいかということです。 handler : this.press这段代码中 。我遇见的问题就是如果我在press函数要用到这个类ContactTelPanel的一些属性,怎么办?

Idea

我在想,我要在press函数中用到这个类的属性,我直接在press用this对象来获取不就行了,但是我错了,比如你在press函数中console.dir(this),看chrome控制台出现的是什么?不幸的是它出现的是Button对象,它的this指针改了。确实有点麻烦,然后我就想了三个方法,如下:

Solution

1 在每个监听事件的函数中传参

代码handler : this.press(this),然后在press函数体中写alert(arguments[0])

出现的情况:确实在这个页面加载的时候就弹出窗口是ContactTelPanel,但是你点击那些按钮的时候它没出现了

原因this.press(this),这样子写javascript解析器会当作调用press函数,然后在你加载页面就执行了

2 在这个ContactTelPanel类中设置全局变量

代码:比如在第五行设置me = this,然后在press函数体中写alert(me)

出现的情况:确实可以在点击按钮的时候弹出窗口,成功了

缺点:污染全局变量,容易被别人无意篡改。比如我在引入这个页面的js后面再引用其他js的时候,在后面的js中设置var me = "monkindey",那么你再点击那个页面的按钮的时候它会弹出123,为不是ContactTelPanel对象

3 简单运用了闭包

代码handler : function(){me.press(me)} 注:me就是ContactTelPanel对象,因为在function中this指针已经是button对象了,所以应该在function外面用me(或者其他变量名)保存this对象,即var me = this

出现的情况:这个当然是成功

4 用call来实现函数绑定

代码handler : function(){ me.press.call(this,me);}

アイデア

このクラスの属性をpress関数で使用したい場合は、このオブジェクトを使用してpressで直接取得できると考えていましたが、たとえば、私は間違っていました。 press 関数 console.dir(this) を使用すると、Chrome コンソールに何が表示されるかわかりますか? 残念ながら、表示されるのは Button オブジェクトであり、その this ポインタが変更されています。確かにちょっと面倒だったので、以下の3つの方法を考えました。

解決策

1 イベントをリッスンする各関数にパラメータを渡す🎜🎜コード🎜 :handler: this.press(this) に、alert(arguments[0])🎜🎜何が起こったのか🎜: このページが読み込まれたときにポップアップ ウィンドウが ContactTelPanel であることは事実ですが、これらのボタンをクリックしても表示されません🎜🎜理由🎜 : this .press(this)、このように書くと、JavaScript パーサーはそれを press 関数の呼び出しとして扱い、ページをロードするときに実行します🎜🎜2 この ContactTelPanel クラスでグローバル変数を設定します🎜🎜コード🎜: たとえば、5 行目に me = this と設定し、alert(me) と記述します🎜🎜 を press 関数本体に追加します。 状況 🎜: ボタンをクリックするとウィンドウをポップアップすることは確かに可能です。 成功 🎜🎜欠点 🎜: グローバル変数が汚染されており、他人によって意図せずに簡単に改ざんされてしまいます。たとえば、このページの JS を導入し、他の JS を参照する場合、後続の JS で var me = "monkindey" を設定すると、そのページのボタンをクリックすると、123 が表示されます。 ContactTelPanel オブジェクト🎜🎜 3 クロージャーの簡単な使用法🎜🎜コード🎜: handler: function(){me.press(me)} 注: me はContactTelPanel オブジェクト。関数内では、このポインターはすでにボタン オブジェクトであるため、このオブジェクトは関数の外で me (または他の変数名) とともに保存する必要があります。つまり、var me = this🎜🎜何が起こるか🎜 : これはもちろん成功です🎜🎜4 呼び出しを使用して関数バインディングを実装します🎜🎜コード🎜:handler: function(){ me .press.call(this,me) ;}🎜🎜関連する推奨事項: 🎜🎜🎜 ES6 JavaScript の関数バインディングとクラス イベント バインディング関数の詳細な説明🎜🎜🎜🎜 JavaScript の難しさ: プロトタイプとコンストラクターの詳細な説明バインディングの例🎜🎜🎜🎜JavaScript 関数バインディング🎜🎜

以上がJavaScript 関数バインディングの使用状況分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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