ホームページ > ウェブフロントエンド > jsチュートリアル > JavaScript でのバインド、呼び出し、および適用関数の使用方法の詳細な紹介

JavaScript でのバインド、呼び出し、および適用関数の使用方法の詳細な紹介

黄舟
リリース: 2017-03-14 15:23:12
オリジナル
1048 人が閲覧しました

プロジェクトチームの他のプログラムにjsを導入する際に、たくさんのコンテンツを用意しましたが、やはり、話すだけでは十分ではなく、実行する必要があります。数日前、ある人がコード内の call() function の使用法について私に質問しました。js を使用してサーバーを作成するプログラマーには javascript を読むことをお勧めします。プログラミングエッセンス』という本、廃人fordは、実際にはマスターによってカバーされていません。その後、segmentfault で同様の質問を見つけましたので、そこで回答した後、ここにメモしました。

まず、jsでクラスや

オブジェクトを定義する方法については、w3schoolのこちらを参照してください。非常に詳しくわかりやすく書かれているので、詳細は説明しません。

JavaScript でのバインド、呼び出し、および適用関数の使用方法の詳細な紹介

bind、call、applyの3つの関数の使い方を紹介するには、jsでの関数の設定をいくつか紹介する必要があります。この部分については、

「JavaScript プログラミングの本質」 の第 4 章を読むことをお勧めします。ここで述べていることはすべてこの本の中に記載されています。

これら 3 つの関数の詳細については、MDN のドキュメントを参照してください:

bindcallapply

ブロックから始めて、segmentfault に関する私の以前の回答を変更しましょう:

js には関数呼び出しの 4 つのモードがあります:

メソッド呼び出し、通常の関数呼び出し、コンストラクター関数呼び出し、および適用/呼び出し呼び出しです。

同時に、どのような関数呼び出しであっても、宣言時に定義した仮引数に加えて、thisと引数の2つの仮引数が自動的に追加されます。

arguments には上記の 3 つの関数が含まれないため、ここではこれについてのみ説明します。この値は、上記 4 の呼び出しモードで異なる値にバインドされます。

メソッド呼び出し:

これは分かりやすいですが、関数はオブジェクトの

プロパティです。例えば、上記の関数のthisはオブジェクトにバインドされています。 a.したがって、this.v はオブジェクト a の属性 v を取得できます。

通常の関数呼び出し:

まだコードを見ています

var a = {     
    v : 0,     
    f : function(xx) {                 
        this.v = xx;     
    } 
} 
a.f(5);
ログイン後にコピー
この時点では、関数 f の this は、ブラウザーで実行されているインタープリター内にある場合は、グローバル オブジェクトにバインドされています。つまり、ここでの this.x が実際にアクセスするのは window.x です。 もちろん、window に x 属性がない場合、このように書くと、js の不正な構文に従って、x が追加されます。 window オブジェクトに属性を追加し、同時に値を割り当てます。

コンストラクター関数の呼び出し:

コンストラクター

は、私が常に js で最も厄介な部分だと思っています。これは、元々 js によって設計されたプロトタイプベースの

オブジェクト指向 実装と互換性がないためです。は、他のクラスベースのオブジェクト指向実装によって誰もが損なわれてしまった習慣に応えるために特別に設計されました。 new

キーワードを指定して関数を呼び出すと、js はそのプロトタイプ属性がこの関数である新しいオブジェクトを作成し、この関数を呼び出すときにこれをこの新しいオブジェクトにバインドします。もちろん、新しいキーワードは

return ステートメントの 動作 も変更しますが、ここではそれについては説明しません。コードを見てください

function f(xx) {         
    this.x = xx; 
} 
f(5);
ログイン後にコピー
上記の関数の書き方と、通常呼び出される関数に違いはありませんが、呼び出す際に関数名の前にキーワード new が追加される点が異なります。 このように、これは拘束されなくなります。前に述べたように、これはグローバル オブジェクトですが、ここで作成される新しいオブジェクトです。そのため、関数を見ただけでは、この関数がコンストラクターとして使用されることを意図しているのか、それともコンストラクターとして使用されるのかがわからないため、このメソッドは実際には非常に危険です。一般的な機能。したがって、jslint では、作成するすべてのコンストラクターが必要であることがわかります。つまり、 new キーワードが使用されたことが判明すると、後続の関数の最初の文字は大文字にする必要があります。区別するには、個人的には 1 つだけ意見があります: 不正行為:)

apply/call call:

我们知道,在 js 里,函数其实也是一个对象,那么函数自然也可以拥有它自己的方法,有点绕,在js 里,每个函数都有一个公共的 prototype —— Function,而这个原型自带有好几个属性和方法,其中就有这里困惑的 bind、call、apply 方法。先说 apply 方法,它让我们构造一个参数数组传递给函数,同时可以自己来设置 this 的值,这就是它最强大的地方,上面的 3 种函数调用方式,你可以看到,this 都是自动绑定的,没办法由你来设,当你想设的时候,就可以用 apply()了。apply 函数接收 2 个参数,第一个是传递给这个函数用来绑定 this 的值,第二个是一个参数数组。

看代码

function a(xx) {         
    this.b = xx; 
} 
var o = {}; 
a.apply(o, [5]); 
alert(a.b);    // undefined 
alert(o.b);    // 5
ログイン後にコピー

是不是很神奇,函数 a 居然可以给 o 加属性值。当然,如果你 apply 的第一个参数传递 null,那么在函数 a 里面 this 指针依然会绑定全局对象。

call() 方法和 apply() 方法很类似,它们的存在都是为了改变 this 的绑定,那 call() 和apply() 有什么区别呢?就我个人看来,没啥鸟区别。。。开玩笑!刚刚说了,上面 apply() 接收两个参数,第一个是绑定 this 的值,第二个是一个参数数组,注意它是一个数组,你想传递给这个函数的所有参数都放在数组里,然后 apply() 函数会在调用函数时自动帮你把数组展开。而 call()呢,它的第一个参数也是绑定给 this 的值,但是后面接受的是不定参数,而不再是一个数组,也就是说你可以像平时给函数传参那样把这些参数一个一个传递。

所以如果一定要说有什么区别的话,看起来是这样的

function a(xx, yy) {     
    alert(xx, yy);     
    alert(this);     
    alert(arguments); 
} 
a.apply(null, [5, 55]); 
a.call(null, 5, 55);
ログイン後にコピー

仅此而已。

最后再来说 bind() 函数,上面讲的无论是 call() 也好, apply() 也好,都是立马就调用了对应的函数,而 bind() 不会, bind() 会生成一个新的函数,bind() 函数的参数跟 call() 一致,第一个参数也是绑定 this 的值,后面接受传递给函数的不定参数。 bind() 生成的新函数返回后,你想什么时候调就什么时候调,看下代码就明白了

var m = {    
    "x" : 1 
}; 
function foo(y) { 
    alert(this.x + y); 
} 
foo.apply(m, [5]); 
foo.call(m, 5); 
var foo1 = foo.bind(m, 5); 
foo1();
ログイン後にコピー

末了来个吐槽,你在 js 里想定义一个函数,于是你会这么写:

function jam() {};
ログイン後にコピー

其实这是 js 里的一种语法糖,它等价于:

var jam = function() {};
ログイン後にコピー

然后你想执行这个函数,脑洞大开的你会这么写:

function jam() {}();
ログイン後にコピー

但是这么写就报错了,其实这种写法也不算错,因为它确实是 js 支持的函数表达式,但是同时 js 又规定以function 开头的语句被认为是函数语句,而函数语句后面是肯定不会带 () 的,所以才报错,于是聪明的人想出来,加上一对括号就可以了。于是就变成了这样:

1(function jam() {}());

这样就定义了一个函数同时也执行它,详情参加 ECMAScript  Expression Statement 章节。

以上がJavaScript でのバインド、呼び出し、および適用関数の使用方法の詳細な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート