5种正确处理JS的this指向的方式
我喜欢在JS中更改函数执行上下文的指向,也称为 this 指向。
例如,咱们可以在类数组对象上使用数组方法:
const reduce = Array.prototype.reduce; function sumArgs() { return reduce.call(arguments, (sum, value) => { return sum += value; }); } sumArgs(1, 2, 3); // => 6
另一方面,this 很难把握。
咱们经常会发现自己用的 this 指向不正确。下面的教你如何简单地将 this 绑定到所需的值。
【相关课程推荐:JavaScript视频教程】
在开始之前,我需要一个辅助函数execute(func),它仅执行作为参数提供的函数。
function execute(func) { return func(); } execute(function() { return 10 }); // => 10
现在,继续理解围绕this错误的本质:方法分离。
1. 方法分离问题
假设有一个类Person包含字段firstName和lastName。此外,它还有一个方法getFullName(),该方法返回此人的全名。如下所示:
function Person(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; this.getFullName = function() { this === agent; // => true return `${this.firstName} ${this.lastName}`; } } const agent = new Person('前端', '小智'); agent.getFullName(); // => '前端 小智'
可以看到Person函数作为构造函数被调用:new Person('前端', '小智')。 函数内部的 this 表示新创建的实例。
getfullname()返回此人的全名:'前端 小智'。正如预期的那样,getFullName()方法内的 this 等于agent。
如果辅助函数执行agent.getFullName方法会发生什么:
execute(agent.getFullName); // => 'undefined undefined'
执行结果不正确:'undefined undefined',这是 this 指向不正确导致的问题。
现在在getFullName() 方法中,this的值是全局对象(浏览器环境中的 window )。 this 等于 window,${window.firstName} ${window.lastName} 执行结果是 'undefined undefined'。
发生这种情况是因为在调用execute(agent.getFullName)时该方法与对象分离。 基本上发生的只是常规函数调用(不是方法调用):
execute(agent.getFullName); // => 'undefined undefined' // 等价于: const getFullNameSeparated = agent.getFullName; execute(getFullNameSeparated); // => 'undefined undefined'
这个就是所谓的方法从它的对象中分离出来,当方法被分离,然后执行时,this 与原始对象没有连接。
1、为了确保方法内部的this指向正确的对象,必须这样做
2、以属性访问器的形式执行方法:agent.getFullName()或者静态地将this绑定到包含的对象(使用箭头函数、.bind()方法等)
方法分离问题,以及由此导致this指向不正确,一般会在下面的几种情况中出现:
回调
// `methodHandler()`中的`this`是全局对象 setTimeout(object.handlerMethod, 1000);
在设置事件处理程序时
// React: `methodHandler()`中的`this`是全局对象 <button onClick={object.handlerMethod}> Click me </button>
接着介绍一些有用的方法,即如果方法与对象分离,如何使this指向所需的对象。
2. 关闭上下文
保持this指向类实例的最简单方法是使用一个额外的变量self:
function Person(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; const self = this; this.getFullName = function() { self === agent; // => true return `${self.firstName} ${self.lastName}`; } } const agent = new Person('前端', '小智'); agent.getFullName(); // => '前端 小智' execute(agent.getFullName); // => '前端 小智'
getFullName()静态地关闭self变量,有效地对this进行手动绑定。
现在,当调用execute(agent.getFullName)时,一切工作正常,因为getFullName()方法内 this 总是指向正确的值。
3. 使用箭头函数
有没有办法在没有附加变量的情况下静态绑定this? 是的,这正是箭头函数的作用。
使用箭头函数重构Person:
function Person(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; this.getFullName = () => `${this.firstName} ${this.lastName}`; } const agent = new Person('前端', '小智'); agent.getFullName(); // => '前端 小智' execute(agent.getFullName); // => '前端 小智'
箭头函数以词法方式绑定this。 简单来说,它使用来自其定义的外部函数this的值。
建议在需要使用外部函数上下文的所有情况下都使用箭头函数。
4. 绑定上下文
现在让咱们更进一步,使用ES6中的类重构Person。
class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } getFullName() { return `${this.firstName} ${this.lastName}`; } } const agent = new Person('前端', '小智'); agent.getFullName(); // => '前端 小智' execute(agent.getFullName); // => 'undefined undefined'
不幸的是,即使使用新的类语法,execute(agent.getFullName)仍然返回“undefined undefined”。
在类的情况下,使用附加的变量self或箭头函数来修复this的指向是行不通的。
但是有一个涉及bind()方法的技巧,它将方法的上下文绑定到构造函数中:
class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; this.getFullName = this.getFullName.bind(this); } getFullName() { return `${this.firstName} ${this.lastName}`; } } const agent = new Person('前端', '小智'); agent.getFullName(); // => '前端 小智' execute(agent.getFullName); // => '前端 小智'
构造函数中的this.getFullName = this.getFullName.bind(this)将方法getFullName()绑定到类实例。
execute(agent.getFullName) 按预期工作,返回'前端 小智'。
5. 胖箭头方法
bind 方式有点太过冗长,咱们可以使用胖箭头的方式:
class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } getFullName = () => { return `${this.firstName} ${this.lastName}`; } } const agent = new Person('前端', '小智'); agent.getFullName(); // => '前端 小智' execute(agent.getFullName); // => '前端 小智'
胖箭头方法getFullName =() =>{…}绑定到类实例,即使将方法与其对象分离。
这种方法是在类中绑定this的最有效和最简洁的方法。
6. 总结
与对象分离的方法会产生 this 指向不正确问题。静态地绑定this,可以手动使用一个附加变量self来保存正确的上下文对象。然而,更好的替代方法是使用箭头函数,其本质上是为了在词法上绑定this。
在类中,可以使用bind()方法手动绑定构造函数中的类方法。当然如果你不用使用 bind 这种冗长方式,也可以使用简洁方便的胖箭头表示方法。
原文:https://github.com/valentinogagliardi/Little-JavaScript-Book/blob/v1.0.0/manuscript/chapter5.md
本文来自 js教程 栏目,欢迎学习!
Atas ialah kandungan terperinci 5种正确处理JS的this指向的方式. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian Pengenalan: Dengan perkembangan teknologi yang berterusan, teknologi pengecaman pertuturan telah menjadi bahagian penting dalam bidang kecerdasan buatan. Sistem pengecaman pertuturan dalam talian berdasarkan WebSocket dan JavaScript mempunyai ciri kependaman rendah, masa nyata dan platform merentas, dan telah menjadi penyelesaian yang digunakan secara meluas. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian.

Alat penting untuk analisis saham: Pelajari langkah-langkah untuk melukis carta lilin dalam PHP dan JS, contoh kod khusus diperlukan Dengan perkembangan pesat Internet dan teknologi, perdagangan saham telah menjadi salah satu cara penting bagi banyak pelabur. Analisis saham adalah bahagian penting dalam membuat keputusan pelabur, dan carta lilin digunakan secara meluas dalam analisis teknikal. Mempelajari cara melukis carta lilin menggunakan PHP dan JS akan memberikan pelabur maklumat yang lebih intuitif untuk membantu mereka membuat keputusan yang lebih baik. Carta candlestick ialah carta teknikal yang memaparkan harga saham dalam bentuk candlestick. Ia menunjukkan harga saham

Teknologi pengesanan dan pengecaman muka adalah teknologi yang agak matang dan digunakan secara meluas. Pada masa ini, bahasa aplikasi Internet yang paling banyak digunakan ialah JS Melaksanakan pengesanan muka dan pengecaman pada bahagian hadapan Web mempunyai kelebihan dan kekurangan berbanding dengan pengecaman muka bahagian belakang. Kelebihan termasuk mengurangkan interaksi rangkaian dan pengecaman masa nyata, yang sangat memendekkan masa menunggu pengguna dan meningkatkan pengalaman pengguna termasuk: terhad oleh saiz model, ketepatannya juga terhad. Bagaimana untuk menggunakan js untuk melaksanakan pengesanan muka di web? Untuk melaksanakan pengecaman muka di Web, anda perlu biasa dengan bahasa dan teknologi pengaturcaraan yang berkaitan, seperti JavaScript, HTML, CSS, WebRTC, dll. Pada masa yang sama, anda juga perlu menguasai visi komputer yang berkaitan dan teknologi kecerdasan buatan. Perlu diingat bahawa kerana reka bentuk bahagian Web

WebSocket dan JavaScript: Teknologi utama untuk merealisasikan sistem pemantauan masa nyata Pengenalan: Dengan perkembangan pesat teknologi Internet, sistem pemantauan masa nyata telah digunakan secara meluas dalam pelbagai bidang. Salah satu teknologi utama untuk mencapai pemantauan masa nyata ialah gabungan WebSocket dan JavaScript. Artikel ini akan memperkenalkan aplikasi WebSocket dan JavaScript dalam sistem pemantauan masa nyata, memberikan contoh kod dan menerangkan prinsip pelaksanaannya secara terperinci. 1. Teknologi WebSocket

Pengenalan kepada cara menggunakan JavaScript dan WebSocket untuk melaksanakan sistem pesanan dalam talian masa nyata: Dengan populariti Internet dan kemajuan teknologi, semakin banyak restoran telah mula menyediakan perkhidmatan pesanan dalam talian. Untuk melaksanakan sistem pesanan dalam talian masa nyata, kami boleh menggunakan teknologi JavaScript dan WebSocket. WebSocket ialah protokol komunikasi dupleks penuh berdasarkan protokol TCP, yang boleh merealisasikan komunikasi dua hala masa nyata antara pelanggan dan pelayan. Dalam sistem pesanan dalam talian masa nyata, apabila pengguna memilih hidangan dan membuat pesanan

Dengan perkembangan pesat kewangan Internet, pelaburan saham telah menjadi pilihan semakin ramai orang. Dalam perdagangan saham, carta lilin adalah kaedah analisis teknikal yang biasa digunakan Ia boleh menunjukkan trend perubahan harga saham dan membantu pelabur membuat keputusan yang lebih tepat. Artikel ini akan memperkenalkan kemahiran pembangunan PHP dan JS, membawa pembaca memahami cara melukis carta lilin saham dan menyediakan contoh kod khusus. 1. Memahami Carta Lilin Saham Sebelum memperkenalkan cara melukis carta lilin saham, kita perlu memahami dahulu apa itu carta lilin. Carta candlestick telah dibangunkan oleh orang Jepun

JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap Pengenalan: Hari ini, ketepatan ramalan cuaca sangat penting kepada kehidupan harian dan membuat keputusan. Apabila teknologi berkembang, kami boleh menyediakan ramalan cuaca yang lebih tepat dan boleh dipercayai dengan mendapatkan data cuaca dalam masa nyata. Dalam artikel ini, kita akan mempelajari cara menggunakan teknologi JavaScript dan WebSocket untuk membina sistem ramalan cuaca masa nyata yang cekap. Artikel ini akan menunjukkan proses pelaksanaan melalui contoh kod tertentu. Kami

Tutorial JavaScript: Bagaimana untuk mendapatkan kod status HTTP, contoh kod khusus diperlukan: Dalam pembangunan web, interaksi data dengan pelayan sering terlibat. Apabila berkomunikasi dengan pelayan, kami selalunya perlu mendapatkan kod status HTTP yang dikembalikan untuk menentukan sama ada operasi itu berjaya dan melaksanakan pemprosesan yang sepadan berdasarkan kod status yang berbeza. Artikel ini akan mengajar anda cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan menyediakan beberapa contoh kod praktikal. Menggunakan XMLHttpRequest
