目次
2.3.2 call
2.3.3 apply
2.3.4 bind
2.4 new绑定
3. 绑定优先级
3.1 隐式绑定 > 默认绑定
3.2 显示绑定 > 隐式绑定
3.3 bind(硬绑定) >  apply/call
3.4 new绑定 > bind绑定
5. 总结
4. 箭头函数 (arrow function)
4.1 箭头函数this
4.2 箭头函数的应用场景 进阶
5.1 this的四种绑定规则
5.2 this的优先级 从高到低
6. 结语
ホームページ 見出し この点を理解してフロントエンド担当者の7割をキャッチアップした記事

この点を理解してフロントエンド担当者の7割をキャッチアップした記事

Sep 06, 2022 pm 05:03 PM
javascript this

この バグ vue2 のこの指摘された問題 でアロー関数を使用したため、同僚が行き詰まり、対応する props# を取得できなくなりました。 ## 。私がそれを紹介したとき、彼はそれを知りませんでした。その後、私はわざとフロントエンド コミュニケーション グループに目を向けました。今のところ、フロントエンド プログラマの少なくとも 70% はまだそれを理解していません。それを共有します。今日はあなたと一緒に thisポイント、何も学んでいないなら、大きな口を立ててください。

1. 場所の呼び出し

    スコープは定義された場所に関連しており、実行される場所とは関係ありません
  • thisポインタは、どこで定義されるかには関係なく、どのように呼び出されるか、そしてどのような形式で呼び出されるかに関係します。
  • this(this) どのように this関数が呼び出されます (覚えておくと便利です)
  • 理解を容易にするために、デフォルトでは厳密モードは有効になっていません

#2. バインディング ルール

上でも紹介しましたが、

this ポインティングは主に呼び方の形式によって決まります。次に、呼び出しルールを紹介します。ルールがなければ何も完成しません。この呼び出しルールを覚えておいてください。難しいことは何もありません。」

    呼び出し元の場所を見つけて、次の 4 つのバインド ルールのどれであるかを判断する必要があります。
  • 次に、これら 4 つのバインド ルールの優先順位も把握しておく必要があります。
  • これら 2 つの点を理解していると、これがどこを指しているのかを簡単に理解できるでしょう。
2.1 デフォルトのバインディング

最も一般的なのは関数です。 used 呼び出しメソッド、呼び出し関数のタイプ: 独立した関数呼び出し

function bar() {
  console.log(this) // window
}
ログイン後にコピー

bar は修飾子のない直接呼び出しであるため、デフォルトのバインディングは
    window
  • ## です。 #厳密モー​​ドでは、this
  • ここは
  • 未定義
  • #2.2 暗黙的なバインディング

最も一般的な用語を使用します。 、それは意味します: オブジェクトには特定のメソッドがあり、そのメソッドはこのオブジェクトを通じてアクセスされ、直接呼び出されます (注: アロー関数は特別であり、これについては後で説明します)
const info = {
  fullName: 'ice',
  getName: function() {
    console.log(this.fullName)
  }
}

info.getName() // 'ice'
ログイン後にコピー

この関数は

info
    呼び出しが開始され、暗黙的なバインディングが実行されるため、現在の
  • thisinfo となり、値は this.fullName を通じてアクセスされます。は間違いなく Ice
  • 暗黙的な損失が正常です

場合によっては、暗黙的な損失が実行され、暗黙的にバインドされた関数がバインドされたオブジェクトが失われます。つまり、デフォルト バインディングになります。デフォルト バインディングの this

値は、現在いる環境。厳密モードかどうか。

const info = {
  fullName: 'ice',
  getName: function() {
    console.log(this.fullName)
  }
}

const fn = info.getName

fn() //undefined
ログイン後にコピー
この場合、暗黙的な損失が行われ、バインドされたオブジェクトが失われることになりますが、なぜこのような問題が発生するのでしょうか?記憶に詳しい人なら簡単に理解できると思います。 ここには直接呼び出しはありませんが、getName に対応するメモリ アドレスは info

を通じて検出され、変数

fn## に割り当てられます。
  • #その後、呼び出しは fn を通じて直接行われました。実際、ここでの本質は、独立した関数呼び出し (window です) です。
  • window
  • fullName 属性を取り出します。この属性は
  • 未定義
  • 暗黙的な損失の高度なである必要があります。最初に理解する必要があるのは、コールバック関数です。実際、これはこのように理解できます。つまり、今は呼び出すのではなく、パラメーターの形式で他の場所に渡し、別の場所で呼び出します。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">//申明变量关键字必须为var var fullName = 'panpan' const info = {   fullName: 'ice',   getName: function() {     console.log(this.fullName)   } } function bar(fn) {   //fn = info.getName   fn() // panpan } bar(info.getName)</pre><div class="contentsignin">ログイン後にコピー</div></div>
  • まず、
bar

fn はコールバック関数

    fn = info.getName
  • です。パラメータの受け渡し これは暗黙的な割り当てです。実際、上記の暗黙的な損失と同じ意味を持っています。それらはすべて fn = info.getName 参照を指しており、これはメモリ アドレス です
  • this
  • が失われているため、関数は独立して呼び出されます。デフォルトのバインディング ルールは、this がグローバル window オブジェクト
  • # であるためです。 ##注: 宣言が「What about
  • var」でなければならないのはなぜですか? var で宣言された変数のみがグローバル window
  • オブジェクトに追加されるためです。
  • If let\const
      使用済みの場合は、いいえ、変数を宣言するための 2 つのキーワードを詳しく紹介します
    • しかし、シナリオによっては、暗黙的な損失を望まない場合があります。どうすればよいですか? ディスプレイ バインディングを導入しましょうあなたへの、つまり固定電話です。
    • 2.3 表示バインディング
    ただし、一部のシナリオでは、
  • this
  • の変更は予期せぬものになります。コールバック関数がどのように実行されるかを制御できないため、呼び出し場所に、これが指す予想されるバインディングがあるかどうかを制御する方法がありません。
次の表示バインディングを使用して、この暗黙的な損失の問題を解決できます。

2.3.1 call/apply/bind

js の「すべての」関数には、いくつかの便利な機能があります。これは、そのプロトタイプ チェーンに関連しています。プロトタイプチェーン js を介して継承を偽装して実装する方法をプロトタイプに導入します。このうち call/apply/bind

の 3 つのメソッドは関数プロトタイプチェーン上のメソッドであり、これらは関数プロトタイプチェーンで呼び出すことができます。関数。

2.3.2 call

  • call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。
    • 第一个参数为固定绑定的this对象
    • 第二个参数以及二以后的参数,都是作为参数进行传递给所调用的函数
  • 备注
    • 该方法的语法和作用与 apply() 方法类似,只有一个区别,就是 call() 方法接受的是一个参数列表,而 apply() 方法接受的是一个包含多个参数的数组
var fullName = 'panpan'

const info = {
  fullName: 'ice',
  getName: function(age, height) {
    console.log(this.fullName, age, height)
  }
}

function bar(fn) {
  fn.call(info, 20, 1.88) //ice 20 1.88
}

bar(info.getName)
ログイン後にコピー

2.3.3 apply

  • call的方法类似,只是参数列表有所不同
    • 参数
      • call  参数为单个传递
      • apply 参数为数组传递
var fullName = 'panpan'

const info = {
  fullName: 'ice',
  getName: function(age, height) {
    console.log(this.fullName, age, height)
  }
}

function bar(fn) {
  fn.apply(info, [20, 1.88]) //ice 20 1.88
}

bar(info.getName)
ログイン後にコピー

2.3.4 bind

  • bindapply/call之间有所不同,bind传入this,则是返回一个this绑定后的函数,调用返回后的函数,就可以拿到期望的this。
  • 参数传递则是
    • 调用bind时,可以传入参数
    • 调用bind返回的参数也可以进行传参
var fullName = 'panpan'

const info = {
  fullName: 'ice',
  getName: function(age, height) {
    console.log(this.fullName, age, height) //ice 20 1.88
  }
}

function bar(fn) {
  let newFn = fn.bind(info, 20)
  newFn(1.88)
}

bar(info.getName)
ログイン後にコピー

2.4 new绑定

  谈到new关键字,就不得不谈构造函数,也就是JS中的 "类",后续原型篇章在跟大家继续探讨这个new关键字,首先要明白以下几点,new Fn()的时候发生了什么,有利于我们理解this的指向。

  • 创建了一个空对象

  • 将this指向所创建出来的对象

  • 把这个对象的[[prototype]] 指向了构造函数的prototype属性

  • 执行代码块代码

  • 如果没有明确返回一个非空对象,那么返回的对象就是这个创建出来的对象

function Person(name, age) {
  this.name = name
  this.age = age

}

const p1 = new Person('ice', 20)

console.log(p1) // {name:'ice', age:20}
ログイン後にコピー
  • 当我调用new Person()的时候,那个this所指向的其实就是p1对象

3. 绑定优先级

3.1 隐式绑定 > 默认绑定

function bar() {
  console.log(this) //info
}

const info = {
  bar: bar
}

info.bar()
ログイン後にコピー
  • 虽然这边比较有些勉强,有些开发者会认为这是默认绑定的规则不能直接的显示谁的优先级高
  • 但是从另外一个角度来看,隐式绑定,的this丢失以后this才会指向widonw或者undefined,变相的可以认为隐式绑定 > 默认绑定

3.2 显示绑定 > 隐式绑定

var fullName = 'global ice'
const info = {
  fullName: 'ice',
  getName: function() {
    console.log(this.fullName) 
  }
}

info.getName.call(this) //global ice
info.getName.apply(this) //global ice
info.getName.bind(this)() //global ice
ログイン後にコピー
  • 通过隐式绑定和显示绑定的一起使用很明显 显示绑定 > 隐式绑定

3.3 bind(硬绑定) >  apply/call

function bar() {
  console.log(this) //123
}

const newFn = bar.bind(123)
newFn.call(456)
ログイン後にコピー

3.4 new绑定 > bind绑定

首先我们来说一下,为什么是和bind比较,而不能对callapply比较,思考下面代码

const info = {
  height: 1.88
}

function Person(name, age) {
  this.name = name
  this.age = age
}

const p1 = new Person.call('ice', 20)

//报错: Uncaught TypeError: Person.call is not a constructor
ログイン後にコピー

new绑定和bind绑定比较

const info = {
  height: 1.88
}

function Person(name, age) {
  this.name = name
  this.age = age
}

const hasBindPerson = Person.bind(info)

const p1 = new hasBindPerson('ice', 20)

console.log(info) //{height: 1.88}
ログイン後にコピー
  • 我们通过bindPerson进行了一次劫持,硬绑定了this为info对象
  • new 返回的固定this的函数
  • 但是我们发现 并不能干预this的指向

3.5 总结

new关键字 > bind > apply/call > 隐式绑定 > 默认绑定

4. 箭头函数 (arrow function)

首先箭头函数是ES6新增的语法

const foo = () => {}
ログイン後にコピー

4.1 箭头函数this

var fullName = 'global ice'

const info = {
  fullName: 'ice',
  getName: () => {
    console.log(this.fullName)
  }
}

info.getName() //global ice
ログイン後にコピー
  • 你会神奇的发现? 为什么不是默认绑定,打印结果为ice
  • 其实这是ES6的新特性,箭头函数不绑定this,它的this是上一层作用域,上一层作用域为window
  • 所以打印的结果是 global ice

4.2 箭头函数的应用场景 进阶

  • 需求: 在getObjName通过this拿到info中的fullName (值为icefullName)
const info = {
  fullName: 'ice',
  getName: function() {
    let _this = this
    return {
      fullName: 'panpan',
      getObjName: function() {
        console.log(this) // obj
        console.log(_this.fullName)
      }
    }
  }
}

const obj = info.getName()
obj.getObjName()
ログイン後にコピー
  • 当我调用 info.getName() 返回了一个新对象

  • 当我调用返回对象的getObjName方法时,我想拿到最外层的fullName,我通过,getObjName的this访问,拿到的this却是obj,不是我想要的结果

  • 我需要在调用info.getName() 把this保存下来,info.getName() 是通过隐式调用,所以它内部的this就是info对象

  • getObjName是obj对象,因为也是隐式绑定,this必定是obj对象,绕了一大圈我只是想拿到上层作用域的this而已,恰好箭头函数解决了这一问题

const info = {
  fullName: 'ice',
  getName: function() {
    return {
      fullName: 'panpan',
      getObjName: () => {
        console.log(this.fullName)
      }
    }
  }
}

const obj = info.getName()
obj.getObjName()
ログイン後にコピー

5. 总结

5.1 this的四种绑定规则

  • 默认绑定

  • 隐式绑定

  • 显示绑定 apply/call/bind(也称硬绑定)

  • new绑定

5.2 this的优先级 从高到低

  • new绑定

  • bind

  • call/apply

  • 隐式绑定

  • 默认绑定

6. 结语

  当一切都看起来不起作用的时候,我就会像个石匠一样去敲打石头,可能敲100次,石头没有任何反应,但是101次,石头可能就会裂为两半 我知道并不是第101次起了作用,而是前面积累所致。

  大家有疑惑可以在评论区留言 第一时间为大家解答。

(学习视频分享:web前端开发

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

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 Dec 17, 2023 pm 02:54 PM

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 はじめに: 技術の継続的な発展により、音声認識技術は人工知能の分野の重要な部分になりました。 WebSocket と JavaScript をベースとしたオンライン音声認識システムは、低遅延、リアルタイム、クロスプラットフォームという特徴があり、広く使用されるソリューションとなっています。この記事では、WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法を紹介します。

WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー Dec 17, 2023 pm 05:30 PM

WebSocketとJavaScript:リアルタイム監視システムを実現するためのキーテクノロジー はじめに: インターネット技術の急速な発展に伴い、リアルタイム監視システムは様々な分野で広く利用されています。リアルタイム監視を実現するための重要なテクノロジーの 1 つは、WebSocket と JavaScript の組み合わせです。この記事では、リアルタイム監視システムにおける WebSocket と JavaScript のアプリケーションを紹介し、コード例を示し、その実装原理を詳しく説明します。 1.WebSocketテクノロジー

JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 Dec 17, 2023 pm 12:09 PM

JavaScript と WebSocket を使用してリアルタイム オンライン注文システムを実装する方法の紹介: インターネットの普及とテクノロジーの進歩に伴い、ますます多くのレストランがオンライン注文サービスを提供し始めています。リアルタイムのオンライン注文システムを実装するには、JavaScript と WebSocket テクノロジを使用できます。 WebSocket は、TCP プロトコルをベースとした全二重通信プロトコルで、クライアントとサーバー間のリアルタイム双方向通信を実現します。リアルタイムオンラインオーダーシステムにおいて、ユーザーが料理を選択して注文するとき

WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 Dec 17, 2023 am 09:39 AM

WebSocket と JavaScript を使用してオンライン予約システムを実装する方法 今日のデジタル時代では、ますます多くの企業やサービスがオンライン予約機能を提供する必要があります。効率的かつリアルタイムのオンライン予約システムを実装することが重要です。この記事では、WebSocket と JavaScript を使用してオンライン予約システムを実装する方法と、具体的なコード例を紹介します。 1. WebSocket とは何ですか? WebSocket は、単一の TCP 接続における全二重方式です。

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 Dec 17, 2023 pm 05:13 PM

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 はじめに: 今日、天気予報の精度は日常生活と意思決定にとって非常に重要です。テクノロジーの発展に伴い、リアルタイムで気象データを取得することで、より正確で信頼性の高い天気予報を提供できるようになりました。この記事では、JavaScript と WebSocket テクノロジを使用して効率的なリアルタイム天気予報システムを構築する方法を学びます。この記事では、具体的なコード例を通じて実装プロセスを説明します。私たちは

簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 Jan 05, 2024 pm 06:08 PM

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

JavaScriptでinsertBeforeを使用する方法 JavaScriptでinsertBeforeを使用する方法 Nov 24, 2023 am 11:56 AM

使用法: JavaScript では、insertBefore() メソッドを使用して、DOM ツリーに新しいノードを挿入します。このメソッドには、挿入される新しいノードと参照ノード (つまり、新しいノードが挿入されるノード) の 2 つのパラメータが必要です。

JavaScript と WebSocket: 効率的なリアルタイム画像処理システムの構築 JavaScript と WebSocket: 効率的なリアルタイム画像処理システムの構築 Dec 17, 2023 am 08:41 AM

JavaScript は Web 開発で広く使用されているプログラミング言語であり、WebSocket はリアルタイム通信に使用されるネットワーク プロトコルです。 2 つの強力な機能を組み合わせることで、効率的なリアルタイム画像処理システムを構築できます。この記事では、JavaScript と WebSocket を使用してこのシステムを実装する方法と、具体的なコード例を紹介します。まず、リアルタイム画像処理システムの要件と目標を明確にする必要があります。リアルタイムの画像データを収集できるカメラ デバイスがあるとします。