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 thisolarak 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, thisuygulamanızdaki genel değişkene başvurur.
"use strict";İşlev deyiminin başlangıcına ifade ekleyerek bunu katı modda çalıştırırsak , thisartık ortamların hiçbirindeki genel değişkene başvurmayacağız. Bu, katı modda karışıklıkları önlemek için yapılır. thisBu 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 forEachve gibi yerel yöntemleri çağırdıysanız slice, zaten thisbu durumda değişkenin Objecto işlevi çağırdığınız anlamına geldiğini bilmelisiniz (Javascript'te, s ve s Objectdahil olmak üzere hemen hemen her şeyin bir olduğunu unutmayın ). Örneğin aşağıdaki kodu ele alalım.ArrayFunction
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, thisdeğişkenin Objectiliş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 thisartı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
newanahtar 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? newAnahtar kelimeyi kullandığımızda ne olacağını görelim .
- İşlevi
newanahtar sözcükle çağırmak derhal bir Objecttür başlatır Person.
- Bunun yapıcısının
Objectyapıcısı olarak ayarlanmıştır Person. Ayrıca, sadece typeof awaldöneceğini unutmayın Object.
- Bu yeni
Objectmodelin prototipi atanır Person.prototype. Bu, Personprototipteki herhangi bir yöntemin veya özelliğin Person, dahil tüm örnekleri için kullanılabilir olacağı anlamına gelir awal.
- Fonksiyonun
Personkendisi çağrılmıştır; thisyeni inşa edilen nesneye referans olması awal.
Çok basit, ha?
Resmi ECMAScript spesifikasyonunun hiçbir yerde bu tür işlevlerin gerçek constructorişlevler olduğunu belirtmediğini unutmayın . Bunlar sadece normal işlevlerdir ve newherhangi 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ı: callveapply
Yani evet, functions 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 callve applyve her ikisi de değerini manipüle etmek için kullanılabilir thisdedikleri 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 thisişlevde fooreferans olarak ayarlanır thisArg. Diğer tüm parametreler callişleve fooargümanlar olarak iletilir .
Yukarıdaki kod {myObj: "is cool"}, [1, 2, 3]konsolda oturum açacaktır . thisHerhangi bir fonksiyonun değerini değiştirmek için oldukça güzel bir yol .
applycallyalnızca iki parametre aldığını kabul etmekle neredeyse aynıdır : thisArgve 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 callve ikinci madde işaretinde tartıştığımız nokta yöntemi çağırma applyile thisset değerini geçersiz kılabilir . Yeterince basit :)
Sunum .... bind!
bindcallve kardeşidir apply. Ayrıca FunctionJavascript'te global yapıcıdan tüm fonksiyonlar tarafından miras alınan bir yöntemdir . bindVe call/ arasındaki fark apply, her ikisinin callve applyaslında işlevi çağıracağıdır. bind, öte yandan thisArgve 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 callve apply, nokta yöntemi çağırma bindile thisset 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. callve applyyeni yapılandırılmış işlevlerden değeri binddö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, thiskapsamla, ö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, thisiç içe kapsamla değiştirilen değerin değiştiğini görüyoruz , ancak thisorijinal kapsamdan değerini istiyorduk . Biz kopyaladı 'Yani thisetmek thatve kullanılan yerine kopyalamak this. Zeki, ha?
Dizin:
thisVarsayılan olarak ne tutulur ?
- Fonksiyonu Object-dot gösterimi ile bir yöntem olarak çağırırsak ne olur?
newAnahtar kelimeyi kullanırsak ne olur ?
- Nasıl değişiklik yapmıyoruz
thisile callve apply?
- Kullanma
bind.
thisİç içe geçmiş sorunları çözmek için kopyalama .