ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript に対する 6 つの障壁

JavaScript に対する 6 つの障壁

黄舟
黄舟オリジナル
2017-02-21 11:17:371347ブラウズ



このコケティッシュな仕組みを考えると、これを理解することは時代を超えたテーマであり、この記事では、この迷惑な妖精を 6 つの部分に分割して釘付けにしようとします。

まず第一に、

これはすべてコンテキストに関するものです。

これは、率直に言うと、現在のコンテキストを所有するボスとコンテキスト オブジェクトを見つけることです。

大きなボスは 6 つのレベルに分けられ、レベルが高いほど、最大のボスのみが認識されます。

第一レベル: 世界の終わり

通常の状況では、最も力の弱いボスが、ブラウザーで使用する場合はウィンドウになります。それは未定義です。

function showThis () {
console.log(this)
}
 
function showStrictThis () {
'use strict'
console.log(this)
}
 
showThis() // window
showStrictThis() // undefined

第 2 レベル: 石を金に変える

第 2 レベルのボスは率直に言います: この関数の前にあるドットを見つけてください。

this を使用する関数が context オブジェクトに属している場合、この context オブジェクトは this にバインドされます。

たとえば、次の例では、boss は returnThis のコンテキスト オブジェクトであるか、returnThis は Boss に属します。

var boss = {
name: 'boss',
returnThis () {
return this
}
}
 
boss.returnThis() === boss // true

次の例に注意してください。答えを思いつくことができますか?

var boss1 = {
name: 'boss1',
returnThis () {
return this
}
}
 
var boss2 = {
name: 'boss2',
returnThis () {
return boss1.returnThis()
}
}
 
var boss3 = {
name: 'boss3',
returnThis () {
var returnThis = boss1.returnThis
return returnThis()
}
}
 
boss1.returnThis() // boss1
boss2.returnThis() // ?
boss3.returnThis() // ?

答えはboss1とwindow ああ、当てはまりましたか?

これを使用する関数を見てください。

boss2.returnThisでは、これを使用する関数はboss1.returnThisなので、これはboss1にバインドされています。

boss3.returnThisでは、これを使用する関数はreturnThisなので、これはスペアタイヤにバインドされています。

これをboss2にバインドするにはどうすればよいですか?

var boss1 = {
name: 'boss1',
returnThis () {
return this
}
}
 
var boss2 = {
name: 'boss2',
returnThis: boss1.returnThis
}
 
boss2.returnThis() //boss2

はい、これを使用する関数が Boss2 に属している限り、可能です。

第 3 レベル: 指先で結婚

第 3 レベルのボスは Object.prototype.call と Object.prototype.apply で、パラメーターを通じてこれを指定できます。 (これを直接割り当てることはできないことに注意してください。this = 2 は ReferenceError を報告します。)

function returnThis () {
return this
}
 
var boss1 = { name: 'boss1' }
 
returnThis() // window
returnThis.call(boss1) // boss1
returnThis.apply(boss1) // boss1

第 4 レベル: 相互

第 4 レベルのボスは Object.prototype.bind で、これは新しい関数を通じて永続性を提供するだけではありません。このバインディングは、第 3 レベルのボスのコマンドもカバーします。

function returnThis () {
return this
}
 
var boss1 = { name: 'boss1'}
 
var boss1returnThis = returnThis.bind(boss1)
 
boss1returnThis() // boss1
 
var boss2 = { name: 'boss2' }
boss1returnThis.call(boss2) // still boss1

第 5 層: 中にはすべてがあります

これを無視してバインドするのが簡単な場所は新しいです。新しい関数を作成すると、これは自動的に新しいオブジェクトにバインドされ、関数が呼び出されます。これは、bind のバインディングをオーバーライドします。

function showThis () {
console.log(this)
}
 
showThis() // window
new showThis() // showThis
 
var boss1 = { name: 'boss1' }
showThis.call(boss1) // boss1
new showThis.call(boss1) // TypeError
 
var boss1showThis = showThis.bind(boss1)
boss1showThis() // boss1
new boss1showThis() // showThis

レベル 6: 軍令の山

最後の強力なボスは、ES2015 のアロー機能です。アロー関数の this はもはや魅力的なものではなく、Lexical this と呼ばれる現在の語彙スコープに永久に封印されており、コードが実行される前に決定できます。他の偉人はそれをカバーできません。

これの利点は、混乱を引き起こすことを恐れずに、コールバック関数の this が現在のスコープを使用するのに便利であることです。

したがって、アロー関数については、それが作成された場所を見てください。

V8 によって実装された語彙スコープに興味がある場合は、ここを参照してください。

function callback (cb) {
cb()
}
 
callback(() => { console.log(this) }) // window
 
var boss1 = {
name: 'boss1',
callback: callback,
callback2 () {
callback(() => { console.log(this) })
}
}
 
boss1.callback(() => { console.log(this) }) // still window
boss1.callback2(() => { console.log(this) }) // boss1

次の奇妙な使用法に注意する必要があります:

var returnThis = () => this
 
returnThis() // window
new returnThis() // TypeError
 
var boss1 = {
name: 'boss1',
returnThis () {
var func = () => this
return func()
}
}
 
returnThis.call(boss1) // still window
 
var boss1returnThis = returnThis.bind(boss1)
boss1returnThis() // still window
 
boss1.returnThis() // boss1
 
var boss2 = {
name: 'boss2',
returnThis: boss1.returnThis
}
 
boss2.returnThis() // boss2

なぜ最終的に Boss2 なのかわからない場合は、「アロー関数については、それが作成された場所を見てください。」という文を理解してください。

上記は JavaScript の 6 つのハードルの内容です。その他の関連コンテンツについては、PHP 中国語 Web サイト (www.php.cn) に注目してください。


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