JavaScript en this
Basit işlev çağırma
Aşağıdaki işlevi göz önünde bulundurun:
function foo() {
console.log("bar");
console.log(this);
}
foo(); // calling the function
Bunu normal modda çalıştırdığımızı, yani katı modun kullanılmadığını unutmayın.
Bir tarayıcıda çalışırken, değeri this
olarak günlüğe kaydedilir window
. Bunun nedeni window
, bir web tarayıcısının kapsamındaki global değişken olmasıdır.
Aynı kod parçasını node.js gibi bir ortamda çalıştırırsanız, this
uygulamanızdaki genel değişkene başvurur.
"use strict";
İşlev deyiminin başlangıcına ifade ekleyerek bunu katı modda çalıştırırsak , this
artık ortamların hiçbirindeki genel değişkene başvurmayacağız. Bu, katı modda karışıklıkları önlemek için yapılır. this
Bu durumda, sadece log olur undefined
, çünkü budur, tanımlanmamıştır.
Aşağıdaki durumlarda, değerini nasıl değiştireceğimizi göreceğiz this
.
Bir nesne üzerinde fonksiyon çağırma
Bunu yapmanın farklı yolları vardır. Javascript'te forEach
ve gibi yerel yöntemleri çağırdıysanız slice
, zaten this
bu durumda değişkenin Object
o işlevi çağırdığınız anlamına geldiğini bilmelisiniz (Javascript'te, s ve s Object
dahil olmak üzere hemen hemen her şeyin bir olduğunu unutmayın ). Örneğin aşağıdaki kodu ele alalım.Array
Function
var myObj = {key: "Obj"};
myObj.logThis = function () {
// I am a method
console.log(this);
}
myObj.logThis(); // myObj is logged
Bir Object
, a içeren bir özellik içeriyorsa Function
, özelliğe yöntem adı verilir. Bu yöntem çağrıldığında, this
değişkenin Object
ilişkili olduğu değişkene her zaman sahip olacaktır . Bu hem katı hem de katı olmayan modlar için geçerlidir.
Bir yöntem başka bir değişkende saklanırsa (veya kopyalanırsa), başvurunun this
artık yeni değişkende korunmadığına dikkat edin. Örneğin:
// continuing with the previous code snippet
var myVar = myObj.logThis;
myVar();
// logs either of window/global/undefined based on mode of operation
Daha yaygın olarak kullanılan bir senaryo dikkate alındığında:
var el = document.getElementById('idOfEl');
el.addEventListener('click', function() { console.log(this) });
// the function called by addEventListener contains this as the reference to the element
// so clicking on our element would log that element itself
new
anahtar kelime
Javascript'te bir yapıcı işlevi düşünün:
function Person (name) {
this.name = name;
this.sayHello = function () {
console.log ("Hello", this);
}
}
var awal = new Person("Awal");
awal.sayHello();
// In `awal.sayHello`, `this` contains the reference to the variable `awal`
Bu nasıl çalışıyor? new
Anahtar kelimeyi kullandığımızda ne olacağını görelim .
- İşlevi
new
anahtar sözcükle çağırmak derhal bir Object
tür başlatır Person
.
- Bunun yapıcısının
Object
yapıcısı olarak ayarlanmıştır Person
. Ayrıca, sadece typeof awal
döneceğini unutmayın Object
.
- Bu yeni
Object
modelin prototipi atanır Person.prototype
. Bu, Person
prototipteki herhangi bir yöntemin veya özelliğin Person
, dahil tüm örnekleri için kullanılabilir olacağı anlamına gelir awal
.
- Fonksiyonun
Person
kendisi çağrılmıştır; this
yeni inşa edilen nesneye referans olması awal
.
Çok basit, ha?
Resmi ECMAScript spesifikasyonunun hiçbir yerde bu tür işlevlerin gerçek constructor
işlevler olduğunu belirtmediğini unutmayın . Bunlar sadece normal işlevlerdir ve new
herhangi bir işlevde kullanılabilir. Sadece onları bu şekilde kullanıyoruz ve bu yüzden onları sadece böyle adlandırıyoruz.
Fonksiyonlardaki çağrı fonksiyonları: call
veapply
Yani evet, function
s de Objects
(ve aslında Javascript'teki birinci sınıf değişkenler) olduğundan, işlevlerin bile ... iyi, işlevlerin kendileri olan yöntemleri vardır.
Tüm fonksiyonlar küresel devralan Function
, ve birçok yöntemden ikisidir call
ve apply
ve her ikisi de değerini manipüle etmek için kullanılabilir this
dedikleri edildiği işlevinde.
function foo () { console.log (this, arguments); }
var thisArg = {myObj: "is cool"};
foo.call(thisArg, 1, 2, 3);
Bu tipik bir kullanım örneğidir call
. Temel olarak ilk parametreyi alır ve this
işlevde foo
referans olarak ayarlanır thisArg
. Diğer tüm parametreler call
işleve foo
argümanlar olarak iletilir .
Yukarıdaki kod {myObj: "is cool"}, [1, 2, 3]
konsolda oturum açacaktır . this
Herhangi bir fonksiyonun değerini değiştirmek için oldukça güzel bir yol .
apply
call
yalnızca iki parametre aldığını kabul etmekle neredeyse aynıdır : thisArg
ve işleve iletilecek bağımsız değişkenleri içeren bir dizi. Yani yukarıdaki call
çağrı şu şekilde tercüme edilebilir apply
:
foo.apply(thisArg, [1,2,3])
Dikkat edin call
ve ikinci madde işaretinde tartıştığımız nokta yöntemi çağırma apply
ile this
set değerini geçersiz kılabilir . Yeterince basit :)
Sunum .... bind
!
bind
call
ve kardeşidir apply
. Ayrıca Function
Javascript'te global yapıcıdan tüm fonksiyonlar tarafından miras alınan bir yöntemdir . bind
Ve call
/ arasındaki fark apply
, her ikisinin call
ve apply
aslında işlevi çağıracağıdır. bind
, öte yandan thisArg
ve ile arguments
önceden ayarlanmış yeni bir işlev döndürür . Bunu daha iyi anlamak için bir örnek alalım:
function foo (a, b) {
console.log (this, arguments);
}
var thisArg = {myObj: "even more cool now"};
var bound = foo.bind(thisArg, 1, 2);
console.log (typeof bound); // logs `function`
console.log (bound);
/* logs `function () { native code }` */
bound(); // calling the function returned by `.bind`
// logs `{myObj: "even more cool now"}, [1, 2]`
Üçü arasındaki farkı görüyor musunuz? İnce ama farklı kullanılıyor. Gibi call
ve apply
, nokta yöntemi çağırma bind
ile this
set değerini de aşacaktır.
Ayrıca, bu üç işlevden hiçbirinin orijinal işlevde herhangi bir değişiklik yapmadığını unutmayın. call
ve apply
yeni yapılandırılmış işlevlerden değeri bind
döndürürken, çağrılmaya hazır yeni yapılandırılmış işlevin kendisini döndürür.
Ekstra şeyler, bunu kopyala
Bazen, this
kapsamla, özellikle iç içe kapsamla değiştiği gerçeğini sevmezsiniz. Aşağıdaki örneğe bir göz atın.
var myObj = {
hello: function () {
return "world"
},
myMethod: function () {
// copy this, variable names are case-sensitive
var that = this;
// callbacks ftw \o/
foo.bar("args", function () {
// I want to call `hello` here
this.hello(); // error
// but `this` references to `foo` damn!
// oh wait we have a backup \o/
that.hello(); // "world"
});
}
};
Yukarıdaki kodda, this
iç içe kapsamla değiştirilen değerin değiştiğini görüyoruz , ancak this
orijinal kapsamdan değerini istiyorduk . Biz kopyaladı 'Yani this
etmek that
ve kullanılan yerine kopyalamak this
. Zeki, ha?
Dizin:
this
Varsayılan olarak ne tutulur ?
- Fonksiyonu Object-dot gösterimi ile bir yöntem olarak çağırırsak ne olur?
new
Anahtar kelimeyi kullanırsak ne olur ?
- Nasıl değişiklik yapmıyoruz
this
ile call
ve apply
?
- Kullanma
bind
.
this
İç içe geçmiş sorunları çözmek için kopyalama .