Prototip kalıtım
null
ve undefined
hariç her ilkel veri türünün bir prototipi vardır. Bu prototip, değerlerle çalışma yöntemleri sağlayan ilgili bir nesne sarmalayıcısıdır. Bir ilkel üzerinde bir yöntem veya özellik araması çağrıldığında JavaScript, ilkel nesneyi perde arkasında sarmalayarak yöntemi çağırır ya da bunun yerine sarmalayıcı nesnede özellik aramasını gerçekleştirir.
Örneğin, bir dize değişmez değerinin kendi yöntemi yoktur ancak ilgili String
nesne sarmalayıcısı sayesinde üzerinde .toUpperCase()
yöntemini çağırabilirsiniz:
"this is a string literal".toUpperCase();
> THIS IS A STRING LITERAL
Buna prototip kalıtım denir. Bu, bir değerin ilgili kurucusundan özellikleri ve yöntemleri devralınmasıdır.
Number.prototype
> Number { 0 }
> constructor: function Number()
> toExponential: function toExponential()
> toFixed: function toFixed()
> toLocaleString: function toLocaleString()
> toPrecision: function toPrecision()
> toString: function toString()
> valueOf: function valueOf()
> <prototype>: Object { … }
Bu yapıcıları kullanarak, değerlerine göre tanımlamak yerine ilkel öğeler oluşturabilirsiniz. Örneğin, String
kurucusunun kullanılması bir dize değişmezi değil, dize nesnesi oluşturur: Bu nesne, yalnızca dize değerimizi değil, kurucunun devralınan tüm özelliklerini ve yöntemlerini de içerir.
const myString = new String( "I'm a string." );
myString;
> String { "I'm a string." }
typeof myString;
> "object"
myString.valueOf();
> "I'm a string."
Sonuç olarak elde edilen nesneler, çoğu durumda onları tanımlamak için kullandığımız değerler gibi davranır. Örneğin, new Number
yapıcısını kullanarak bir sayı değeri tanımlamak Number
prototipinin tüm yöntemlerini ve özelliklerini içeren bir nesneyle sonuçlansa da bu nesnelerde matematiksel operatörleri tam sayılarda kullanacağınız gibi kullanabilirsiniz:
const numberOne = new Number(1);
const numberTwo = new Number(2);
numberOne;
> Number { 1 }
typeof numberOne;
> "object"
numberTwo;
> Number { 2 }
typeof numberTwo;
> "object"
numberOne + numberTwo;
> 3
JavaScript'in yerleşik prototip kalıtım özelliği, bu yapıcıların pratik bir fayda sağlamadığı anlamına geldiğinden bu yapıcıları çok nadiren kullanmanız gerekir. Oluşturucuları kullanarak ilkel oluşturmak da beklenmedik sonuçlara yol açabilir. Bunun nedeni, sonucun basit bir değişmez değer değil, bir nesne olmasıdır:
let stringLiteral = "String literal."
typeof stringLiteral;
> "string"
let stringObject = new String( "String object." );
stringObject
> "object"
Bu durum, katı karşılaştırma operatörlerinin kullanımını karmaşık hale getirebilir:
const myStringLiteral = "My string";
const myStringObject = new String( "My string" );
myStringLiteral === "My string";
> true
myStringObject === "My string";
> false
Otomatik noktalı virgül ekleme (ASI)
JavaScript yorumlayıcıları, bir komut dosyasını ayrıştırırken atlanan noktalı virgül örneklerini düzeltmeye çalışmak için otomatik noktalı virgül ekleme (ASI) adlı bir özellik kullanabilir. JavaScript ayrıştırıcı, izin verilmeyen bir jetonla karşılaşırsa aşağıdaki koşullardan biri veya daha fazlası geçerli olduğu sürece olası söz dizimi hatasını düzeltmek için söz konusu jetondan önce noktalı virgül eklemeye çalışır:
- Bu jeton, önceki jetondan satır sonu işaretiyle ayrılır.
- Bu jeton
}
. - Önceki jeton
)
'tür ve eklenen noktalı virgül,do
…while
ifadesinin bitiş noktalı virgülü olur.
Daha fazla bilgi için ASI kurallarına bakın.
Örneğin, aşağıdaki ifadelerden sonra noktalı virgüllerin atlanması ASI nedeniyle söz dizimi hatasına neden olmaz:
const myVariable = 2
myVariable + 3
> 5
Ancak ASI, aynı satırdaki birden fazla ifadeyi hesaba katamaz. Aynı satıra birden fazla ifade yazarsanız bunları noktalı virgüllerle ayırdığınızdan emin olun:
const myVariable = 2 myVariable + 3
> Uncaught SyntaxError: unexpected token: identifier
const myVariable = 2; myVariable + 3;
> 5
ASI, JavaScript'e yerleştirilmiş bir tür söz dizimi esnekliği değil, hata düzeltme girişimidir. Doğru kod oluşturmak için bu işleve güvenmek zorunda kalmamak amacıyla uygun yerlerde noktalı virgül kullandığınızdan emin olun.
Yüksek güvenlik modu
JavaScript'in nasıl yazıldığına dair standartlar, dilin ilk tasarımı sırasında düşünülen her şeyin çok ötesine geçti. JavaScript'in beklenen davranışında yapılan her yeni değişiklik, eski web sitelerinde hatalara neden olmamalıdır.
ES5, mevcut uygulamaları bozmadan JavaScript semantiğiyle ilgili bazı uzun süredir devam eden sorunları ele almak için "katı mod"u kullanıma sunar. Bu mod, bir komut dosyasının tamamı veya tek bir işlev için daha kısıtlayıcı bir dil kuralı grubunu etkinleştirmenin bir yoludur. Yüksek güvenlik modunu etkinleştirmek için bir komut dosyasının veya işlevin ilk satırında "use strict"
dize değişmezini ve ardından noktalı virgül kullanın:
"use strict";
function myFunction() {
"use strict";
}
Katı mod, belirli "güvenli olmayan" işlemleri veya desteği sonlandırılmış özellikleri engeller, yaygın "sessiz" hatalar yerine açık hatalar verir ve gelecekteki dil özellikleriyle çakışabilecek söz dizimi kullanımlarını yasaklar. Örneğin, değişken kapsamı ile ilgili erken tasarım kararları, geliştiricilerin var
anahtar kelimesini atlayarak bir değişkeni tanımlarken kapsayıcı bağlamdan bağımsız olarak yanlışlıkla genel kapsamı "kirletme" olasılığını artırıyordu:
(function() {
mySloppyGlobal = true;
}());
mySloppyGlobal;
> true
Modern JavaScript çalışma zamanları, bu davranışı düzeltirken bu davranışa dayalı web sitelerini yanlışlıkla veya kasıtlı olarak bozma riskini göze almalıdır. Bunun yerine modern JavaScript, geliştiricilerin yeni çalışmalar için katı modu etkinleştirmesine izin vererek ve katı modu varsayılan olarak yalnızca eski uygulamaları bozmayacak yeni dil özellikleri bağlamında etkinleştirerek bu sorunu önler:
(function() {
"use strict";
mySloppyGlobal = true;
}());
> Uncaught ReferenceError: assignment to undeclared variable mySloppyGlobal
"use strict"
değerini dize değişmezi olarak yazmanız gerekir.