この バグ
、vue2 のこの指摘された問題
でアロー関数を使用したため、同僚が行き詰まり、対応する props# を取得できなくなりました。 ## 。私がそれを紹介したとき、彼はそれを知りませんでした。その後、私はわざとフロントエンド コミュニケーション グループに目を向けました。今のところ、フロントエンド プログラマの少なくとも 70% はまだそれを理解していません。それを共有します。今日はあなたと一緒に
thisポイント、何も学んでいないなら、大きな口を立ててください。
1. 場所の呼び出し
- スコープは定義された場所に関連しており、実行される場所とは関係ありません
- this
ポインタは、どこで定義されるかには関係なく、どのように呼び出されるか、そしてどのような形式で呼び出されるかに関係します。
- this
(this) どのように this関数が呼び出されます (覚えておくと便利です)
理解を容易にするために、デフォルトでは厳密モードは有効になっていません
#2. バインディング ルール
上でも紹介しましたが、this ポインティングは主に呼び方の形式によって決まります。次に、呼び出しルールを紹介します。ルールがなければ何も完成しません。この呼び出しルールを覚えておいてください。難しいことは何もありません。」
- 呼び出し元の場所を見つけて、次の 4 つのバインド ルールのどれであるかを判断する必要があります。
- 次に、これら 4 つのバインド ルールの優先順位も把握しておく必要があります。
- これら 2 つの点を理解していると、これがどこを指しているのかを簡単に理解できるでしょう。
最も一般的なのは関数です。 used 呼び出しメソッド、呼び出し関数のタイプ: 独立した関数呼び出し
function bar() { console.log(this) // window }bar は修飾子のない直接呼び出しであるため、デフォルトのバインディングは
- window
-
## です。 #厳密モードでは、
this ここは - 未定義
最も一般的な用語を使用します。 、それは意味します: オブジェクトには特定のメソッドがあり、そのメソッドはこのオブジェクトを通じてアクセスされ、直接呼び出されます (注: アロー関数は特別であり、これについては後で説明します) const info = {
fullName: 'ice',
getName: function() {
console.log(this.fullName)
}
}
info.getName() // 'ice'
この関数は
info- 呼び出しが開始され、暗黙的なバインディングが実行されるため、現在の
- this
は
infoとなり、値は
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
属性を取り出します。この属性は 未定義 -
暗黙的な損失の高度な
である必要があります。最初に理解する必要があるのは、コールバック関数です。実際、これはこのように理解できます。つまり、今は呼び出すのではなく、パラメーターの形式で他の場所に渡し、別の場所で呼び出します。
<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>
まず、
の 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
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
-
bind
与apply/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
比较,而不能对call
和apply
比较,思考下面代码
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}
- 我们通过
bind
对Person
进行了一次劫持,硬绑定了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
(值为ice
的fullName
)
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前端开发)

ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

mPDF
mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

WebStorm Mac版
便利なJavaScript開発ツール

VSCode Windows 64 ビットのダウンロード
Microsoft によって発売された無料で強力な IDE エディター

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。
