Rumah > Soal Jawab > teks badan
Saya berharap dapat mencari penjelasan yang jelas tentang perkara yang dilakukan oleh kata kunci "ini" dan cara menggunakannya dengan betul.
Nampaknya berkelakuan pelik dan saya tidak faham sepenuhnya mengapa.
this
Bagaimana ia berfungsi dan bila anda perlu menggunakannya?
P粉0879514422023-10-13 14:03:41
Berbanding dengan bahasa lain, this
关键字在 JavaScript 中的行为有所不同。在面向对象语言中,this
关键字指的是该类的当前实例。在 JavaScript 中,this
的值由函数的调用上下文 (context.function()
) dan kedudukan panggilannya ditentukan. p>
<强>1. Apabila digunakan dalam konteks global
Apabila anda menggunakannya dalam konteks global this
时,它会绑定到全局对象(浏览器中的window
)
document.write(this); //[object Window]
Apabila anda menggunakan this
时,this
di dalam fungsi yang ditakrifkan dalam konteks global anda masih terikat dengan objek global kerana fungsi itu sebenarnya adalah kaedah konteks global. < /p>
function f1() { return this; } document.write(f1()); //[object Window]
Panggil pada objek f1
是一个全局对象的方法。因此我们也可以在 window
di atas, seperti ini:
function f() { return this; } document.write(window.f()); //[object Window]
<强>2. Apabila digunakan di dalam kaedah objek
Apabila anda menggunakan this
关键字时,this
di dalam kaedah objek ia mengikat objek "terus" yang melampirkan.
var obj = { name: "obj", f: function () { return this + ":" + this.name; } }; document.write(obj.f()); //[object Object]:obj
Saya telah meletakkan perkataan "segera" dalam petikan berganda di atas. Ini adalah untuk menunjukkan bahawa jika objek bersarang dalam objek lain, this
terikat pada objek induk terdekat.
var obj = { name: "obj1", nestedobj: { name:"nestedobj", f: function () { return this + ":" + this.name; } } } document.write(obj.nestedobj.f()); //[object Object]:nestedobj
Walaupun anda menambah fungsi sebagai kaedah pada objek secara eksplisit, ia masih mengikut peraturan di atas, iaitu this
masih menunjuk kepada objek induk langsung.
var obj1 = { name: "obj1", } function returnName() { return this + ":" + this.name; } obj1.f = returnName; //add method to object document.write(obj1.f()); //[object Object]:obj1
<强>3. Apabila memanggil fungsi tanpa konteks
Digunakan this
时,它会绑定到全局对象(浏览器中的window
) apabila anda memanggilnya di dalam fungsi tanpa sebarang konteks (iaitu bukan pada sebarang objek) (walaupun jika fungsi itu ditakrifkan di dalam objek).
var context = "global"; var obj = { context: "object", method: function () { function f() { var context = "function"; return this + ":" +this.context; }; return f(); //invoked without context } }; document.write(obj.method()); //[object Window]:global
Cuba semua dengan fungsi
Kita juga boleh menggunakan fungsi untuk mencuba perkara di atas. Tetapi masih terdapat beberapa perbezaan.
this
. untuk menentukan mereka. new
dahulu. Di bawah saya mencuba semua yang saya lakukan di atas dengan Object dan this
tetapi mula-mula mencipta fungsi dan bukannya menulis objek secara langsung.
/********************************************************************* 1. When you add variable to the function using this keyword, it gets added to the function prototype, thus allowing all function instances to have their own copy of the variables added. *********************************************************************/ function functionDef() { this.name = "ObjDefinition"; this.getName = function(){ return this+":"+this.name; } } obj1 = new functionDef(); document.write(obj1.getName() + "
"); //[object Object]:ObjDefinition /********************************************************************* 2. Members explicitly added to the function protorype also behave as above: all function instances have their own copy of the variable added. *********************************************************************/ functionDef.prototype.version = 1; functionDef.prototype.getVersion = function(){ return "v"+this.version; //see how this.version refers to the //version variable added through //prototype } document.write(obj1.getVersion() + "
"); //v1 /********************************************************************* 3. Illustrating that the function variables added by both above ways have their own copies across function instances *********************************************************************/ functionDef.prototype.incrementVersion = function(){ this.version = this.version + 1; } var obj2 = new functionDef(); document.write(obj2.getVersion() + "
"); //v1 obj2.incrementVersion(); //incrementing version in obj2 //does not affect obj1 version document.write(obj2.getVersion() + "
"); //v2 document.write(obj1.getVersion() + "
"); //v1 /********************************************************************* 4. `this` keyword refers to the immediate parent object. If you nest the object through function prototype, then `this` inside object refers to the nested object not the function instance *********************************************************************/ functionDef.prototype.nestedObj = { name: 'nestedObj', getName1 : function(){ return this+":"+this.name; } }; document.write(obj2.nestedObj.getName1() + "
"); //[object Object]:nestedObj /********************************************************************* 5. If the method is on an object's prototype chain, `this` refers to the object the method was called on, as if the method was on the object. *********************************************************************/ var ProtoObj = { fun: function () { return this.a } }; var obj3 = Object.create(ProtoObj); //creating an object setting ProtoObj //as its prototype obj3.a = 999; //adding instance member to obj3 document.write(obj3.fun()+"
");//999 //calling obj3.fun() makes //ProtoObj.fun() to access obj3.a as //if fun() is defined on obj3
<强>4. Apabila digunakan di dalam pembina .
Apabila fungsi digunakan sebagai pembina (iaitu, apabila dipanggil menggunakan kata kunci new
关键字调用时),函数体内的 this
), < /p> dalam badan fungsi menghala ke objek baharu yang sedang dibina.
var myname = "global context"; function SimpleFun() { this.myname = "simple function"; } var obj1 = new SimpleFun(); //adds myname to obj1 //1. `new` causes `this` inside the SimpleFun() to point to the // object being constructed thus adding any member // created inside SimipleFun() using this.membername to the // object being constructed //2. And by default `new` makes function to return newly // constructed object if no explicit return value is specified document.write(obj1.myname); //simple function<强>5. Apabila digunakan di dalam fungsi yang ditakrifkan pada rantai prototaip 🎜
Jika kaedah berada pada rantai prototaip objek, maka this
dalam kaedah merujuk kepada objek yang kaedah dipanggil, seolah-olah kaedah itu ditakrifkan pada objek itu.
var ProtoObj = { fun: function () { return this.a; } }; //Object.create() creates object with ProtoObj as its //prototype and assigns it to obj3, thus making fun() //to be the method on its prototype chain var obj3 = Object.create(ProtoObj); obj3.a = 999; document.write(obj3.fun()); //999 //Notice that fun() is defined on obj3's prototype but //`this.a` inside fun() retrieves obj3.a
<强>6. Fungsi panggilan dalaman(), apply() dan bind()
Function.prototype
. this
yang akan digunakan semasa melaksanakan fungsi. Mereka juga boleh menghantar sebarang hujah kepada fungsi asal apabila ia dipanggil. fun.apply(obj1 [, argsArray])
将 obj1
设置为 this
内的值code>fun() 并调用 fun()
,传递 argsArray
fun.apply(obj1 [, argsArray])fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])
- 设置 obj1 作为 fun()
内 this
的值,并调用 fun()
fun() , menghantar elemen argsArray
sebagai hujahnya. < /code>
fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])
- 返回对函数的引用fun
,其中 fun 内的 this
绑定到 obj1
,并且 fun
的参数绑定到指定的参数 arg1、arg2, arg3,...
- Tetapkan obj1 sebagai apply
、call
和 bind
之间的区别一定已经很明显了。 apply
允许将参数指定为类似数组的对象,即具有数字 length
属性和相应的非负整数属性的对象。而 call
允许直接指定函数的参数。 apply
和 call
fun() menghantar
this
fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])
fun
, di mana menyeronokkan ialah 🎜 terikat kepada 🎜obj1 dan hujah 🎜fun terikat kepada hujah yang ditentukan 🎜arg1, arg2, arg3,.... 🎜
🎜Kini, perbezaan antara 🎜apply, 🎜call dan 🎜bind mestilah jelas. 🎜apply membenarkan hujah ditentukan sebagai objek seperti tatasusunan, iaitu objek dengan sifat 🎜length angka dan sifat integer bukan negatif yang sepadan. Dan 🎜panggilan membolehkan parameter fungsi ditentukan secara langsung. Kedua-dua 🎜apply dan 🎜call segera panggil fungsi dalam konteks yang ditentukan dan dengan parameter yang ditentukan. bind, sebaliknya, hanya mengembalikan fungsi terikat kepada nilai dan argumen ini yang ditentukan. Kita boleh menangkap rujukan kepada fungsi yang dikembalikan ini dengan memberikannya kepada pembolehubah, yang kemudiannya boleh kita panggil pada bila-bila masa. 🎜
🎜
function add(inc1, inc2) { return this.a + inc1 + inc2; } var o = { a : 4 }; document.write(add.call(o, 5, 6)+"🎜🎜7. 🎜🎜🎜 di dalam pengendali acara
"); //15 //above add.call(o,5,6) sets `this` inside //add() to `o` and calls add() resulting: // this.a + inc1 + inc2 = // `o.a` i.e. 4 + 5 + 6 = 15 document.write(add.apply(o, [5, 6]) + "
"); //15 // `o.a` i.e. 4 + 5 + 6 = 15 var g = add.bind(o, 5, 6); //g: `o.a` i.e. 4 + 5 + 6 document.write(g()+"
"); //15 var h = add.bind(o, 5); //h: `o.a` i.e. 4 + 5 + ? document.write(h(6) + "
"); //15 // 4 + 5 + 6 = 15 document.write(h() + "
"); //NaN //no parameter is passed to h() //thus inc2 inside add() is `undefined` //4 + 5 + undefined = NaN
this
来引用相应的元素。这种直接的函数分配可以使用 addeventListener
方法或通过 onclick
terus dalam fungsi pengendali acara.
)内使用 this
, ia merujuk kepada elemen this
会解析为全局对象 window
digunakan secara tidak langsung melalui fungsi lain yang dipanggil dalam pengendali acara atau sifat acara. attachEvent
untuk melampirkan fungsi pada pengendali acara. Daripada memberikan fungsi kepada pengendali acara (dengan itu mencipta kaedah fungsi elemen), ia memanggil fungsi pada acara (dengan berkesan memanggilnya dalam konteks global). Saya syorkan JSFiddle.
ssscccUsing `this` "directly" inside event handler or event property
Using `this` "indirectly" inside event handler or event property
IE only:
<强>8. this
Dalam fungsi anak panah, this
的行为类似于公共变量:它将从其词法范围继承。定义箭头函数的函数的 this
将是箭头函数的 this
berkelakuan seperti pembolehubah awam: ia akan diwarisi daripada skop leksikalnya.
fungsi anak panah.
Jadi, ini adalah kelakuan yang sama seperti:
(function(){}).bind(this)🎜Lihat kod di bawah: 🎜
const globalArrowFunction = () => {
return this;
};
console.log(globalArrowFunction()); //window
const contextObject = {
method1: () => {return this},
method2: function(){
return () => {return this};
}
};
console.log(contextObject.method1()); //window
const contextLessFunction = contextObject.method1;
console.log(contextLessFunction()); //window
console.log(contextObject.method2()()) //contextObject
const innerArrowFunction = contextObject.method2();
console.log(innerArrowFunction()); //contextObject
P粉1565327062023-10-13 11:53:32
此
ialah kata kunci dalam JavaScript yang merupakan atribut konteks pelaksanaan. Penggunaan utamanya adalah dalam fungsi dan pembina.
this
Peraturannya agak mudah (jika anda berpegang kepada amalan terbaik).
this
dalam spesifikasiECMAScript standarddefinisithis
melalui operasi abstrak (disingkatkan sebagai AO) ResolveThisBinding:
Rekod persekitaran global, Rekod persekitaran modul, dan Rekod persekitaran fungsi masing-masing mempunyai kaedah GetThisBinding mereka sendiri.
GetThisEnvironment AO mencari LexicalEnvironment bagi konteks pelaksanaan menjalankan semasa dan mencari rekod persekitaran menaik yang paling hampir (dengan mengulangi sifat [[OuterEnv]]nya) yang mempunyai ini< /em> mengikat ini mengikat
ini. . Proses ini berakhir dengan satu daripada tiga jenis rekod persekitaran. this
Nilai biasanya bergantung pada sama ada kod berada dalam
. this
值,因此每当建立新的执行上下文时,this
Nilai pulangan
konteks pelaksanaan semasa, jadi setiap kali konteks pelaksanaan baharu diwujudkan, akan menyelesaikan kepada nilai yang berbeza. Ini juga boleh berlaku apabila konteks pelaksanaan semasa diubah suai. Subseksyen berikut menyenaraikan lima senario di mana ini mungkin berlaku.
Anda boleh meletakkan sampel kod ke dalam
Ini ialah kod skrip yang dinilai di peringkat teratas, mis
Harta [[GlobalThisValue]] rekod persekitaran global sentiasa ditetapkan kepada objek global yang ditentukan hos, boleh diakses melalui Modul telah diperkenalkan dalam ECMAScript 2015. Ini berfungsi untuk modul cth. menyebabkan sentiasa 1. Konteks pelaksanaan global dalam skrip
dalam konteks global. Modul secara tersirat dalam this
Apabila dalam konteks pelaksanaan global awal skrip, menilai menyebabkan globalThis
globalThis
( Web 上的 window
,Node.js 上的 global
(tetingkap di web
, Node.js global
Dokumentasi di MDN). Ikuti langkah InitializeHostDefinedRealm untuk mengetahui cara sifat [[GlobalThisValue]] dijana. 2. Konteks pelaksanaan global dalam modul
内部时,而不是简单的
this
GetThisBinding mengambil langkah berikut:
this
的值在全局上下文中始终是未定义
mod ketat.
panggilan: eval
langsungdan tidak langsung. Perbezaan ini telah wujud sejak edisi kelima ECMAScript.
eval
调用通常类似于 eval(
...);
或 (eval)(
...< code>); (或 ((eval))(
…);
dll.). 1 Ini hanya langsung (jika ungkapan panggilan menepati corak sempit). 2eval
调用涉及以任何其他方式调用函数引用eval
。它可以是 eval?.(
...)
, (
..., eval)(
...)< /code>, window.eval(
...)
, eval.call(
...,
...)给定 const aliasEval1 = eval; 等。 window.aliasEval2 = eval;
,也可以是 aliasEval1(
…)
、aliasEval2(
…)
代码>.分别给出 const originalEval = eval; window.eval = (x) => originalEval(x);
,调用 eval(
…)
juga tidak langsung. Lihat jawapan chuckj untuk "(1, eval)('this') vs eval('this') dalam JavaScript?" dan Dmitry Soshnikov ECMA-262- 5 butiran – Bab 2: Mod Ketat (Arkib), untuk kes di mana anda mungkin menggunakan panggilan eval()
tidak langsung.
PerformEval melaksanakan kod eval
代码。它创建一个新的 声明性环境记录 作为其 LexicalEnvironment,这是 GetThisEnvironment 从中获取 this
eval. Ia mencipta
baharu sebagai LexicalEnvironmentnya, iaitu GetThisEnvironmentthis
出现在eval
untuk mendapatkan ini daripada > nilai.
dalam kod, GetThisEnvironment dipanggil dan nilainya dikembalikan.
< /code>dicipta
rekod alam
yang melaksanakan penilaian tidak langsung). 🎜 🎜 🎜Ini bermaksud: 🎜this
值不会改变;它取自名为 eval
. this
值是全局对象 (globalThis
). 新函数
怎么样? — new Function
与eval
Serupa, tetapi ia tidak memanggil kod dengan serta-merta; ini Pengikatan tidak terpakai di mana-mana di sini kecuali apabila memanggil fungsi, yang berfungsi dengan baik seperti yang diterangkan dalam subseksyen seterusnya.
Masukkan kod fungsi apabila memanggil fungsi .
Terdapat empat kategori sintaks untuk fungsi panggilan.
Panggilan fungsi sebenar berlaku di Panggilan AO, yang ditentukan oleh konteks panggilan menggunakan ThisValue parameter ini diluluskan dalam senarai panjang panggilan yang berkaitan dengan panggilan. Panggil memanggil [[Panggil]] slot dalaman fungsi. Ini memanggil PrepareForOrdinaryCall, di mana rekod persekitaran fungsi baharu telah dibuat:
Selain itu, terdapat juga medan [[ThisValue]] dalam rekod persekitaran fungsi:
PanggilanNewFunctionEnvironment juga menetapkan sifat [[ThisBindingStatus]] bagi persekitaran fungsi.
[[Panggil]] juga memanggil OrdinaryCallBindThis, di mana thisArgument yang sesuai ditentukan berdasarkan:
Selepas pengesahan, kaedah BindThisValue rekod persekitaran fungsi yang baru dicipta akhirnya dipanggil untuk benar-benar menetapkan medan [[ThisValue]] untuk ditambahkan pada thisArgument.
Akhir sekali, medan ini ialah rekod persekitaran fungsi GetThisBinding AO mendapat nilai this
dari lokasi berikut:
Sekali lagi, penentuan tepat nilai ini bergantung kepada banyak faktor; ini hanyalah gambaran umum. Dengan latar belakang teknikal ini, mari kita lihat semua contoh konkrit.
Apabila mengira fungsi anak panah, sifat objek fungsi slot dalaman [[ThisMode]] ditetapkan kepada "leksikal" dalam OrdinaryFunctionCreate. p>
Di OrdinaryCallBindThis ia memerlukan fungsi F:
Ini hanya bermakna bahawa baki algoritma yang mengikat ini dilangkau. Fungsi anak panah tidak mengikat nilai ini mereka sendiri.
Jadi, apakah this
dalam fungsi anak panah? Untuk menyemak ResolveThisBinding dan GetThisEnvironment, kaedah HasThisBinding secara eksplisit mengembalikan false.
Jadi kami secara berulang mencari persekitaran luaran. Proses ini akan berakhir dalam satu daripada tiga persekitaran dengan pengikatan ini.
Ini hanya bermaksud bahawa, dalam badan fungsi anak panah, this
berasal daripada skop leksikal fungsi anak panah , atau dengan kata lain (dari Fungsi anak panah vs. pengisytiharan/ungkapan fungsi: adakah ia setara/komutatif? ):
Dalam fungsi biasa (fungsi
, kaedah function
、方法),this
) , ditentukan oleh kaedah panggilan fungsi
Di sinilah "variasi tatabahasa" ini berguna.
Pertimbangkan objek ini yang mengandungi fungsi:
const refObj = { func: function(){ console.log(this); } };atau: 🎜
const refObj = { func(){ console.log(this); } };
Dalam mana-mana panggilan fungsi berikut, func
内的 this
值将为 refObj
. 1< /p>
refObj.func()
refObj["func"]()
refObj?.func()
refObj.func?.()
refObj.func``
Jika fungsi yang dipanggil secara sintaksis adalah sifat objek asas, maka objek asas itu akan menjadi "rujukan" panggilan, yang dalam kes biasa ialah nilai this
的值。上面链接的评估步骤对此进行了解释;例如,在 refObj.func()
(或 refObj["func"]()
)中,CallMemberExpression 是整个表达式 refObj.func()
,它由 MemberExpression refObj.func
和 参数 ()
ini. Langkah penilaian yang dipautkan di atas menerangkan perkara ini; contohnya, dalam
), refObj.func
和 refObj
CallMemberExpression
refObj.func
作为值是可调用的函数对象;相应的引用用于确定this
().
Selain itu, ?.()
之前、``
memainkan tiga peranan: <代码>
代码>
Semuanya adalah rujukan, dan
Semuanya adalah nilai.
refObj.func
时为 refObj
;或 foo.bar
code> 当应用于 foo.bar.baz
Mengikat.
Pautan pilihan dan contoh templat teg berfungsi sangat serupa: pada asasnya, rujukan didahului dengan
().
this
。简单属性不会影响执行上下文,例如这里,this
untuk menentukan sama ada ia secara sintaksis merupakan sifat objek. Ia cuba mendapatkan atribut [[Base]] rujukan (cth. apabila digunakan pada < 的调用/代码> ). Jika anda menulisnya sebagai harta,
GetThisValuethis
.Nota: Cara Penetap/Penetap berfungsi, berkenaan dalam skop global:
const o = { a: 1, b: this.a, // Is `globalThis.a`. [this.a]: 2 // Refers to `globalThis.a`. };🎜tanpa rujukan asas, mod ketat dan 🎜🎜dengan🎜🎜🎜 🎜Panggilan tanpa rujukan asas biasanya merupakan fungsi yang tidak dipanggil sebagai atribut. Contohnya: 🎜
func(); // As opposed to `refObj.func();`.🎜Ini juga berlaku apabila 🎜lulus atau menetapkan kaedah🎜, atau apabila menggunakan 🎜 pengendali koma🎜. Di sinilah perbezaan antara rekod rujukan dan nilai adalah relevan. 🎜
Perhatikan bahawa fungsi j
:按照规范,您会注意到j
只能返回函数对象(Value)本身,而不能返回引用记录。因此,基本引用 refObj
tiada.
const g = (f) => f(); // No base ref. const h = refObj.func; const j = () => refObj.func; g(refObj.func); h(); // No base ref. j()(); // No base ref. (0, refObj.func)(); // Another common pattern to remove the base ref.
EvaluateCall panggilan panggilan, di mana thisValue adalah undefined. Ini berbeza dalam OrdinaryCallBindThis (F: fungsi objek; thisArgument: thisValue dihantar ke Panggil): < /p>
Nota: Langkah 5 menetapkan nilai sebenar this
的实际值设置为严格模式下提供的 thisArgument - 在本例中为 undefined
。在“草率模式”下,未定义或 null thisArgument 会导致 this
kepada thisArgument yang disediakan dalam mod ketat - dalam kes ini, undefined
. Dalam "mod ceroboh", tidak ditentukan atau batal
menyebabkan menjadi nilai ini global. Jika IsPropertyReference
mengembalikanfalse, maka EvaluateCall mengambil langkah berikut:
Ini tidak ditentukan Nilai ini Boleh datang daripada: refEnv sec-with-statement-runtime-semantics-evaluation" rel="noreferrer"> . Dalam kes ini, thisValue Juga kelakuan yang mengikat. Symbol.unscopables
(MDN 上的文档)来控制 with
akan menjadi objek pengikat. this
Untuk meringkaskan, setakat ini:
function f1(){
console.log(this);
}
function f2(){
console.log(this);
}
function f3(){
console.log(this);
}
const o = {
f1,
f2,
[Symbol.unscopables]: {
f2: true
}
};
f1(); // Logs `globalThis`.
with(o){
f1(); // Logs `o`.
f2(); // `f2` is unscopable, so this logs `globalThis`.
f3(); // `f3` is not on `o`, so this logs `globalThis`.
}
"use strict"; function f(){ console.log(this); } f(); // Logs `undefined`. // `with` statements are not allowed in strict-mode code.Perhatikan bahawa apabila mengira
.call
, .apply
,.bind
ia tidak penting di mana fungsi normal ditakrifkan.
.call
, .apply
, .bind
, thisArg dan primitif
Satu lagi akibat daripada langkah 5
Untuk menyemak ini, mari perkenalkan satu lagi sumber nilai ini: tiga kaedah yang mengatasi pengikatan ini: 4
Function.prototype.apply(thisArg, argArray)
Function.prototype.
{调用
, 绑定
} (thisArg, ...args)
李>
.bind
.call
和 .apply
mencipta fungsi mengikat yang pengikatan ini sudah ditetapkan kepada Arg ini dan tidak boleh ditukar lagi. .call
dan .apply
ini.call
和 .apply
直接映射到 Call ,使用指定的thisArg。 .bind
untuk terikat kepada Arg ini.
.call
dan .apply
peta terus ke Panggil
thisArg yang dinyatakan. .bind
Gunakan BoundFunctionCreate
[[Panggil ]] sendiri
, yang mencari slot dalaman [[BoundThis]] bagi objek fungsi.Contoh menetapkan nilai tersuai
iniObject("s")
或 new String("s")
:
function f(){
console.log(this);
}
const myObj = {},
g = f.bind(myObj),
h = (m) => m();
// All of these log `myObj`.
g();
f.bind(myObj)();
f.call(myObj);
h(g);
Untuk objek, ini adalah sama dalam mod ketat dan tidak ketat.
Sekarang, cuba berikan nilai mentah: this
function f(){ console.log(this); } const myString = "s", g = f.bind(myString); g(); // Logs `String { "s" }`. f.call(myString); // Logs `String { "s" }`.Dalam mod tidak ketat, primitif dipaksa ke bentuk pembalut objeknya. Ia adalah jenis objek yang sama yang anda dapat semasa memanggil
"use strict"; function f(){ console.log(this); } const myString = "s", g = f.bind(myString); g(); // Logs `"s"`. f.call(myString); // Logs `"s"`.
新
Perpustakaan yang menggunakan kaedah ini seperti set jQuery ke elemen DOM yang dipilih di sini: $("button").click(function(){ console.log(this); // Logs the clicked button. });
Pembina, new
运算符将函数作为构造函数调用时,EvaluateNew 调用 Construct,它调用 [[Construct]] 方法。如果函数是基本构造函数(即不是 class extends
...{
...}
),它会设置 thisArgument到从构造函数的原型创建的新对象。构造函数中 this
上设置的属性最终将出现在生成的实例对象上。 this
Kelas
baharu
, EvaluateNew ialah dipanggil Construct🎜, yang memanggil kaedah [[Construct]] 🎜. Jika fungsi itu ialah pembina asas (iaitu bukan class extends
...{
...}
), ia akan menetapkan 🎜thisArgument🎜 kepada nilai daripada Objek baru yang dicipta oleh prototaip pembina. Sifat yang ditetapkan pada 🎜 dalam pembina akhirnya akan muncul pada objek contoh yang dijana. 🎜 dikembalikan secara tersirat melainkan anda secara eksplisit mengembalikan nilai bukan primitif anda sendiri. 🎜class
ialah cara baharu mencipta pembina, yang diperkenalkan dalam ECMAScript 2015.
function Old(a){ this.p = a; } const o = new Old(1); console.log(o); // Logs `Old { p: 1 }`. class New{ constructor(a){ this.p = a; } } const n = new New(1); console.log(n); // Logs `New { p: 1 }`.
Takrifan kelas secara tersirat dalam mod ketat:
class A{ m1(){ return this; } m2(){ const m1 = this.m1; console.log(m1()); } } new A().m2(); // Logs `undefined`.
超级
H4>
new
行为的例外是 class extends
...{
...}
,如上所述。派生类在调用时不会立即设置其 this 值;它们只有在通过一系列 super
调用到达基类后才会这样做(在没有自己的构造函数
的情况下隐式发生)。不允许在调用 super
之前使用 this
.
Panggil super
super
调用有一个特殊的规则。它使用 BindThisValue 将 this
Memanggil super constructor dengan nilai
super
. Ia menggunakan BindThisValueuntuk menetapkan
kepada rekod persekitaran tersebut.
class DerivedNew extends New{ constructor(a, a2){ // Using `this` before `super` results in a ReferenceError. super(a); this.p2 = a2; } } const n2 = new DerivedNew(1, 2); console.log(n2); // Logs `DerivedNew { p: 1, p2: 2 }`.
class
5. Medan kelas penilaian
Medan contoh dan medan statik telah diperkenalkan dalam ECMAScript 2022.
Apabila menilai , ClassDefinitionEvaluation dilaksanakan, mengubah suai konteks pelaksanaan yang sedang berjalan. Untuk setiap this
this
#x
Jika medan tidak statik,
Medan peribadi (cth. ) dan kaedah ditambahkan pada persekitaran peribadi.
this
adalah cadangan this
TC39 Fasa 3
class Demo{ a = this; b(){ return this; } static c = this; static d(){ return this; } // Getters, setters, private modifiers are also possible. } const demo = new Demo; console.log(demo.a, demo.b()); // Both log `demo`. console.log(Demo.c, Demo.d()); // Both log `Demo`.
1:(o.f)()
等价于 o.f()
; (f)()
相当于 f()
. Artikel 2ality ini (Arkib). Lihat terutamanya Cara menilai ParenthesizedExpression.
2: Ia mestilah MemberExpression em>, tidak boleh menjadi harta, mesti mempunyai [[ReferencedName]] dengan tepat "eval", dan mestilah objek intrinsik %eval%.
3: Setiap kali spesifikasi mengatakan "biar ref menjadi hasil menilai X", X ialah beberapa ungkapan yang langkah penilaiannya perlu anda cari. Contohnya, menilai MemberExpression atau CallExpression ialah algoritma ini. Sebahagian daripada mereka menjana rekod rujukan.
4: Terdapat beberapa kaedah asli dan hos lain yang membenarkan menyediakan nilai ini, terutamanya Array.prototype.map
, Array.prototype.forEach
, dsb. Menerima Array.prototype.map
、< code>Array.prototype.forEach 等接受 thisArg 作为第二个参数。任何人都可以创建自己的方法来更改 this
,例如 (func, thisArg) => func.bind(thisArg)
、(func, thisArg) => func。 call(thisArg)
Arg ini sebagai hujah kedua. Sesiapa sahaja boleh mencipta kaedah mereka sendiri untuk menukar , seperti (func, thisArg) => func.bind(thisArg)
, (func, thisArg) => func. call(thisArg)
dsb. Seperti biasa,
Hanya untuk keseronokan, uji pemahaman anda dengan beberapa contoh
this
Untuk setiap coretan kod, jawab soalan berikut: "Apakah nilai
Untuk mendedahkan jawapan, klik pada kotak kelabu.
if(true){ console.log(this); // What is `this` here? }
globalThis
. Garis yang ditanda dinilai dalam konteks pelaksanaan global awal.
const obj = {}; function myFun(){ return { // What is `this` here? "is obj": this === obj, "is globalThis": this === globalThis }; } obj.method = myFun; console.log(obj.method());