Instagram hesabımda, günlük olarak çoktan seçmeli Javascript soruları paylaşıyorum, ayrıca burada da paylaşacağım!
Temelden ileri düzeye: Javascript'i ne kadar iyi bildiğinizi test edin, bilginizi biraz tazeleyin ya da mülakatanıza hazırlanın! 💪 🚀 Repoyu haftalık olarak yeni sorularla güncelliyorum. Son güncelleme: Last update: 14 Temmuz
Cevaplar, soruların altında gizlenmiştir. Görmek için sadece tıklayın. İyi şanşlar ❤️
Mevcut dillerin listesi:
- English
- العربية
- اللغة العامية - Egyptian Arabic
- Bosanski
- Deutsch
- Español
- 日本語
- 한국어
- Português Brasil
- Русский
- Українська мова
- Tiếng Việt
- 中文版本
- Türkçe
function sayHi() {
console.log(name);
console.log(age);
var name = "Lydia";
let age = 21;
}
sayHi();
- A:
Lydia
veundefined
- B:
Lydia
veReferenceError
- C:
ReferenceError
ve21
- D:
undefined
veReferenceError
Cevap
Fonksiyonun içinde, önce var
anahtar kelimesi ile name
değişkenini tanımladık. Bu demektir ki, değişken varsayılan değeri olan undefined
ile "hoisting" (hafızada alan oluşturma aşaması) olur, ta ki gerçekten değişkene değer ataması yaptığımız satıra varana dek. name
değişkenini loglayama çalıştığımız satırda henüz değişkeni tanımlamadık, bu yüzden hala undefined
değerini saklıyor.
let
(ve const
) anahtar kelimelerine sahip değişkenler de "hoisted" olur, ama var
'ın aksine ilk değer ataması yapılmaz. Değişkenleri tanımladığımız (ilk değer ataması yaptığımız) satırdan önce erişilebilir değillerdir. Bu, "geçici ölü alan / geçici değişmez çıktı alanı", "temporal dead zone", olarak adlandırılır. Değişkenlere, tanımlanmadan önce erişmeye çalıştığımız zaman, Javascript ReferenceError
hatası fırlatır.
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1);
}
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1);
}
- A:
0 1 2
ve0 1 2
- B:
0 1 2
ve3 3 3
- C:
3 3 3
ve0 1 2
Cevap
Javascript'deki olay kuyruğundan dolayı, setTimeout
callback fonksiyonu, döngü uygulandıktan sonra çağrılır. i
değişkeni, ilk döngü sırasında var
anahtar kelimesi ile tanımlandığından, bu değişken globaldir. Döngü boyunca, ++
unary operatörünü kullanarak, i
'nin değerini her seferinde 1
arttırdık. İlk örnekte, setTimeout
callback fonksiyonu çağrıldığı zaman, i
'nin değeri 3
'e eşitti.
İkinci döngüde, i
değişkeni let
anahtar kelimesi kullanılarak tanımlandı: let
(ve const
) ile tanımlanan değişkenler "block-scope"dur (block {}
arasındaki herhangi bir şeydir). Her bir tekrarda, i
yeni değere sahip olacak ve her değer döngü içinde "scoped" olacak.
const shape = {
radius: 10,
diameter() {
return this.radius * 2;
},
perimeter: () => 2 * Math.PI * this.radius
};
console.log(shape.diameter());
console.log(shape.perimeter());
- A:
20
ve62.83185307179586
- B:
20
veNaN
- C:
20
ve63
- D:
NaN
ve63
Cevap
diameter
sıradan bir fonksiyonken, perimeter
'in arrow fonksiyon olduğuna dikkat edin.
Arrow fonksiyonlarda, this
anahtar kelimesi, sıradan fonksiyonların aksine, kendi sardığı mevcut scope'u referans alır. Bu demektir ki, perimeter
'i çağırdığımız zaman, shape
objesini değil, kendi sardığı scope'u referans alıyor (örneğin window).
Bu objede, radius
değeri olmadığından undefined
döndürüyor.
+true;
!"Lydia";
- A:
1
andfalse
- B:
false
andNaN
- C:
false
andfalse
Cevap
Artı (unary plus), işlemeye çalıştığı değişkeni sayıya çevirmeye çalışır. true
1
ve false
0
demektir.
'Lydia'
harf dizisi doğrusal ("truthy") bir değerdir. Aslında sorduğumuz şey, "bu doğrusal değer yanlış-ımsı ("falsy") mı?". Bu da false
döndürür.
const bird = {
size: "small"
};
const mouse = {
name: "Mickey",
small: true
};
- A:
mouse.bird.size
geçerli değildir - B:
mouse[bird.size]
geçerli değildir - C:
mouse[bird["size"]]
geçerli değildir - D: Hepsi geçerlidir
Cevap
Javascript'te, tüm nesne keyleri string'dir (Symbol olmadıkları müddetçe). Keyleri, string olarak yazmadıysak bile, arka planda string'e çevrilirler.
Javascript, ifadeleri yorumlar (ya da açar ("unboxes")). Köşeli parentez notasyonu kullandığımız zaman, Javascript ilk [
görür ve ]
bulana kadar devam eder. Ancak ondan sonra ifadeyi hesaplar.
mouse[bird.size]
: Önce bird.size
çalıştırılır, o da "small"
demektir. mouse["small"]
, true
döndürür.
Ancak, nokta notasyonunda bu gerçekleşmez. mouse
, bird
diye bir keye sahip değildir ki bu da mouse.bird
, undefined
demektir. Sonra, nokta notasyonunu kullanarak size
'a ulaşmak istiyoruz: mouse.bird.size
. mouse.bird
, undefined
olduğundan, aslında ulaşmaya çalıştığımız undefined.size
. Bu geçerli değil ve Cannot read property "size" of undefined
'a benzer bir hata fırlatacaktır.
let c = { greeting: "Hey!" };
let d;
d = c;
c.greeting = "Hello";
console.log(d.greeting);
- A:
Hello
- B:
Hey!
- C:
undefined
- D:
ReferenceError
- E:
TypeError
Cevap
Javascript'te tüm nesneler, birbirlerine eşitlendikleri zaman referansları ile etkileşime girerler.
Önce, c
değişkeni bir nesnenin değerini tutuyor. Sonra, d
'ye aynı referansı atadık ki bu referans da c
'nin sahip olduğu nesnedir.
Bir nesneyi değiştirdiğiniz zaman, hepsini değiştirirsiniz.
let a = 3;
let b = new Number(3);
let c = 3;
console.log(a == b);
console.log(a === b);
console.log(b === c);
- A:
true
false
true
- B:
false
false
true
- C:
true
false
false
- D:
false
true
true
Cevap
new Number()
yerleşik bir yapıcı fonksiyondur ("function constructor"). Sayı ("number") gibi gözükse de gerçekten bir sayı değil: bir kaç ekstra özelliğe sahip ve o bir nesne.
==
operatörünü kullandığımız zaman, sadece aynı değer'e sahip olup olmadığını kontrol eder. İkisi de 3
değerine sahip, yani true
döndürür.
Ancak, ===
kullandığımız zaman değer ve tip aynı olmalıdır. Öyle değil: new Number()
, sayı ("number") değildir, nesnedir. İkisi de false
döndürür.
class Chameleon {
static colorChange(newColor) {
this.newColor = newColor;
return this.newColor;
}
constructor({ newColor = "green" } = {}) {
this.newColor = newColor;
}
}
const freddie = new Chameleon({ newColor: "purple" });
console.log(freddie.colorChange("orange"));
- A:
orange
- B:
purple
- C:
green
- D:
TypeError
Cevap
colorChange
fonksiyonu statiktir. Statik methodlar, sadece oluşturuldukları kurucuda var olmak için tasarlanmıştır ve herhangi bir "children"a aktarılamaz. freddie
, "child" olduğundan, fonksiyon aktarılmadı ve freddie
üzerinden erişilebilir değil: TypeError
hatası fırlatılır.
let greeting;
greetign = {}; // Yazım hatası!
console.log(greetign);
- A:
{}
- B:
ReferenceError: greetign is not defined
- C:
undefined
Cevap
Nesneyi loglar çünkü global nesne üzerinde boş bir nesne oluşturduk. greeting
'i greetign
olarak yanlış yazdığımız zaman, JS yorumlayıcısı bunu global.greetign = {}
olarak gördü (ya da tarayıcı içinde window.greetign = {}
).
Bundan kaçınmak için, "use strict"
kullanabiliriz. Bu, bir değişkene herhangi bir atama yapmadan önce tanımladığınızdan emin olmanızı sağlar.
function bark() {
console.log("Woof!");
}
bark.animal = "dog";
- A: Hiç bir şey, tamamen iyi!
- B:
SyntaxError
. Fonksiyonlara bu şekilde özellik atayamazsın. - C:
"Woof"
şeklinde loglanır. - D:
ReferenceError
Cevap
Javascript'te bu mümkün, çünkü fonksiyonlar nesnedir! (Primitive tiplere nazaran her şey nesnedir)
Fonksiyon özel bir nesne tipidir. Yazdığınız kod asıl fonksiyon değil. Fonksiyon, özelliklere sahip bir nesnedir. Bu özellik çalıştırabilme kapasitesine sahiptir ("invocable").
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
const member = new Person("Lydia", "Hallie");
Person.getFullName = function() {
return `${this.firstName} ${this.lastName}`;
};
console.log(member.getFullName());
- A:
TypeError
- B:
SyntaxError
- C:
Lydia Hallie
- D:
undefined
undefined
Cevap
Sıradan fonksiyonlarla yaptığınız gibi bir yapıcıya ("constructor") özellik ekleyemezsiniz. Eğer, tek seferde tüm nesnelere özellik eklemek isterseniz, bunun yerine prototype kullanmalısınız. Yani bu durumda,
Person.prototype.getFullName = function() {
return `${this.firstName} ${this.lastName}`;
};
member.getFullName()
çalışmış olacak. Bu neden faydalı? Diyelim ki, yapıcının kendisine bu methodu ekledik. Belki de tüm Person
instance'leri bu methoda ihtiyaç duymuyor. Bu özelliğe sahip olduklarından dolayı, her bir instance hafızadan yer alır, bu da bir sürü hafıza israfı demek. Bunun yerine, eğer sadece prototype'a eklersek, hafızadan sadece bir tek yer alırız ve yine de tüm instanceler bu özelliğe erişebilir!
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
const lydia = new Person("Lydia", "Hallie");
const sarah = Person("Sarah", "Smith");
console.log(lydia);
console.log(sarah);
- A:
Person {firstName: "Lydia", lastName: "Hallie"}
veundefined
- B:
Person {firstName: "Lydia", lastName: "Hallie"}
vePerson {firstName: "Sarah", lastName: "Smith"}
- C:
Person {firstName: "Lydia", lastName: "Hallie"}
ve{}
- D:
Person {firstName: "Lydia", lastName: "Hallie"}
veReferenceError
Cevap
sarah
için new
anahtar kelimesi kullanmadık. new
kullandığınız zaman, oluşturduğumuz yeni boş nesneyi referans gösterir. Lakin, new
'i eklemezseniz, global nesne'yi referans gösterir!
this.firstName
, "Sarah"
'a eşittir ve this.lastName
, "Smith"
'e eşittir dedik. Aslında yaptığımız, global.firstName = 'Sarah'
ve global.lastName = 'Smith'
diye tanımlamaydı. sarah
'ın kendisi undefined
olarak kalır.
- A: Target > Capturing > Bubbling
- B: Bubbling > Target > Capturing
- C: Target > Bubbling > Capturing
- D: Capturing > Target > Bubbling
Cevap
capturing aşaması süresince, olay ata ("ancestor) elemanlardan hedef elemana doğru gider. Daha sonra target elemana ulaşır ve bubbling başlar.
- A: doğru
- B: yanlış
Cevap
Bütün nesneler prototiplere ("prototypes") sahiptir, temel nesne, base object, hariç. Temel nesne, kullanıcı tarafından oluşturulmuş nesnedir, ya da new
anahtar kelimesi kullanarak oluşturulmuş bir nesnedir. Temel nesne bazı method ve özelliklere erişebilir, .toString
gibi. Yerleşik gelen Javascript methodlarını kullanabilme sebebi budur! Buna benzer tüm methodlar prototip üzerinden erişebilir. Her ne kadar Javascript, methodu direkt olarak nesneniz üzerinden bulamasa da, prototip zinciri üzerinden aşağıya doğru gider ve orada bulur, böylece sizin için erişebilir yapar.
function sum(a, b) {
return a + b;
}
sum(1, "2");
- A:
NaN
- B:
TypeError
- C:
"12"
- D:
3
Cevap
Javascript dinamik tipli dildir: değişkenlerin hangi tip olduğunu belirtmeyiz. Değerler otomatik olarak diğer tipi bilmeden dönüştürebilir, bu implicit type coercion, örtük tip dönüşümü, olarak adlandırılır. Coercion bir tipi diğer bir tipe dönüştürmektir.
Bu örnekte, JavaScript sayı olan 1
'i string'e dönüştürüyor, fonksiyonun mantıklı olması ve değer döndürmesi için. Sayısal tip (1
) ve string tip (2
)'nin toplanması sırasında, sayıya string olarak muamele edilir. Stringleri "Hello" + "World"
şeklinde birleştirebiliriz, yani burada olan "1" + "2"
ki bu da "12"
döndürür.
let number = 0;
console.log(number++);
console.log(++number);
console.log(number);
- A:
1
1
2
- B:
1
2
2
- C:
0
2
2
- D:
0
1
2
Cevap
son ek, postfix, ++
unary operatörü:
- Değer döndürür (
0
döndürür) - Değeri arttırır (sayı şimdi
1
)
ön ek, prefix, ++
unary operatörü:
- Değeri arttırır (sayı şimdi
2
) - Değeri döndürür (
2
döndürür)
Burada 0 2 2
döner.
function getPersonInfo(one, two, three) {
console.log(one);
console.log(two);
console.log(three);
}
const person = "Lydia";
const age = 21;
getPersonInfo`${person} is ${age} years old`;
- A:
"Lydia"
21
["", " is ", " years old"]
- B:
["", " is ", " years old"]
"Lydia"
21
- C:
"Lydia"
["", " is ", " years old"]
21
Cevap
Eğer "tagged template literals" kullanırsanoz, ilk argumanın değeri her zaman string değerler dizisidir. Geriye kalan argumanlar, ifadeye geçilen değerleri alır.
function checkAge(data) {
if (data === { age: 18 }) {
console.log("You are an adult!");
} else if (data == { age: 18 }) {
console.log("You are still an adult.");
} else {
console.log(`Hmm.. You don't have an age I guess`);
}
}
checkAge({ age: 18 });
- A:
You are an adult!
- B:
You are still an adult.
- C:
Hmm.. You don't have an age I guess
Cevap
Eşitliği test ederken, nesneler referanslarına göre kıyaslanırken primitifler değerlerine göre kıyaslanır. Javascript, nesnelerin referanslarının hafızada aynı konumda olup olmadığını kontrol eder.
Kıyasladığımız iki nesne bu şekilde değilse: parametre olarak geçtiğimiz nesne, hafızada eşitliğini kontrol ettiğimiz nesneden farklı bir konumu referans gösterir.
Bu sebepten, { age: 18 } === { age: 18 }
ve { age: 18 } == { age: 18 }
, ikisi de false
döndürür.
function getAge(...args) {
console.log(typeof args);
}
getAge(21);
- A:
"number"
- B:
"array"
- C:
"object"
- D:
"NaN"
Cevap
Yayma operatorü, "spread operator", (...args
) argumanların dahil olduğu bir dizi döndürür. Dizi bir nesnedir, bu yüzden typeof args
"object"
döndürür.
function getAge() {
"use strict";
age = 21;
console.log(age);
}
getAge();
- A:
21
- B:
undefined
- C:
ReferenceError
- D:
TypeError
Cevap
"use strict"
ile, yanlışlıkla global değişkenler tanımlamadığınızdan emin olabilirsiniz. age
değişkenini hiç tanımlamadık ve "use strict"
kullandığımızdan, referans hatası fırlatacaktır. Eğer "use strict"
kullanmasaydık, age
özelliği global nesneye eklenmiş olacağından, çalışmış olacaktı.
const sum = eval("10*10+5");
- A:
105
- B:
"105"
- C:
TypeError
- D:
"10*10+5"
Cevap
eval
, string olarak geçilen kodu çalıştırır. Eğer bir ifadeyse, bu durumdaki gibi, ifadeyi çalıştırır. İfade 10 * 10 + 5
. Bu 105
sayısını döndürür.
sessionStorage.setItem("cool_secret", 123);
- A: Sonsuza kadar, veri kaybolmaz.
- B: Kullanıcı sekmeyi kapatınca.
- C: Kullanıcı tamamen tarayıcıyı kapattığı zaman, sadece sekmeyi değil.
- D: Kullanıcı bilgisayarını kapattığı zaman.
Cevap
sessionStorage
içinde saklanan veri sekme kapatıldıktan sonra kaldırılır.
Eğer localStorage
kullandıysanız, veri sonsuza kadar orada olacaktır, örnek olarak localStorage.clear()
çalıştırılmadığı sürece.
var num = 8;
var num = 10;
console.log(num);
- A:
8
- B:
10
- C:
SyntaxError
- D:
ReferenceError
Cevap
var
anahtar kelimesi ile aynı isme sahip birden çok değişken tanımlayabilirsiniz. O halde değişken son değeri tutacak.
Bunu let
ya da const
ile yapamazsınız, "block-scoped" olduklarından dolayı.
const obj = { 1: "a", 2: "b", 3: "c" };
const set = new Set([1, 2, 3, 4, 5]);
obj.hasOwnProperty("1");
obj.hasOwnProperty(1);
set.has("1");
set.has(1);
- A:
false
true
false
true
- B:
false
true
true
true
- C:
true
true
false
true
- D:
true
true
true
true
Cevap
Tüm nesne anahtarları (Symbol'ler hariç) arka planda string'dir, kendiniz string olarak yazmasanız bile. Bu sebepten obj.hasOwnProperty('1')
da true
döndürür.
Set için bu şekilde çalışmaz. Setimizde '1'
yok: set.has('1')
false
döndürür. Setimiz sayısal tip 1
'e sahip, set.has(1)
true
döndürür.
const obj = { a: "one", b: "two", a: "three" };
console.log(obj);
- A:
{ a: "one", b: "two" }
- B:
{ b: "two", a: "three" }
- C:
{ a: "three", b: "two" }
- D:
SyntaxError
Cevap
Eğer aynı ada sahip iki tane anahtarınız, "key", varsa, anahtar değiştirilecektir. Hala ilk konumunda olacaktır ama son belirtilen değerle birlikte.
26. JavaScript global yürütme konteksti, "global execution context", sizin için iki şey oluşturur: global nesne, ve "this" anahtar kelimesi.
- A: doğru
- B: yanlış
- C: değişir
Cevap
Temel yürütme konteksti, global yürütme kontekstidir: kodunuzda her yerde erişilebilir olan şeydir.
for (let i = 1; i < 5; i++) {
if (i === 3) continue;
console.log(i);
}
- A:
1
2
- B:
1
2
3
- C:
1
2
4
- D:
1
3
4
String.prototype.giveLydiaPizza = () => {
return "Just give Lydia pizza already!";
};
const name = "Lydia";
name.giveLydiaPizza();
- A:
"Just give Lydia pizza already!"
- B:
TypeError: not a function
- C:
SyntaxError
- D:
undefined
Cevap
String
, özellikler de ekleyebileceğimiz tümleşik bir yapıcıdır. Prototipine bir method ekledim sadece. Primitif stringler, string prototip fonksiyonu tarafından üretilen string nesnesine otomatik olarak dönüştürülür. Bu yüzden, tüm stringler (string nesneleri) bu methoda erişebilir!
const a = {};
const b = { key: "b" };
const c = { key: "c" };
a[b] = 123;
a[c] = 456;
console.log(a[b]);
- A:
123
- B:
456
- C:
undefined
- D:
ReferenceError
Cevap
Nesne keyleri otomatik olarak stringe dönüştürülür. a
nesnesine değeri 123
olacak şekilde, bir nesneyi key olarak atamaya çalışıyoruz.
Ancak, bir nesnesi string hale getirince, "[Object object]"
olur. Dolayısıyla burada söylediğimiz, a["Object object"] = 123
. Sonra, aynı şeyi tekrar yapmayı deniyoruz. c
, dolaylı olarak string hale getirdiğimiz başka bir nesne. O halde, a["Object object"] = 456
.
Sonra, a[b]
'yi logluyoruz, ki aslında o da a["Object object"]
. Onu da 456
olarak atamıştık, o yüzden 456
döndürür.
const foo = () => console.log("First");
const bar = () => setTimeout(() => console.log("Second"));
const baz = () => console.log("Third");
bar();
foo();
baz();
- A:
First
Second
Third
- B:
First
Third
Second
- C:
Second
First
Third
- D:
Second
Third
First
Cevap
Bir setTimeout
fonksiyonumuz var ve ilk onu çalıştırdık. Yine de en son loglandı.
Bunun nedeni tarayıcılarda, "runtime engine"'a sahip olmamamızdan, WebAPI
denilen bir şeye sahibiz. WebAPI
, örneğin DOM ile çalışması için bize, setTimeout
fonksiyonunu verir.
callback WebAPI'a eklendikten sonra, setTimeout
fonksiyonun kendisi (callback hariç!) hafıza bloğundan atılır, "popped off the stack".
Şimdi, foo
çalıştı ve "First"
loglandı.
foo
hafıza bloğundan atıldı ve baz
çalıştı. "Third"
loglandı.
WebAPI, her ne zaman bir şeyler hazırsa hafıza bloğuna öylece ekleyemez. Onun yerine callback fonksiyonunu, queue diye adlandıralan bir şeye ekler.
Burası olay döngüsünün çalışmaya başlayacapı yerdir. olay döngüsü, event loop, hafıza bloğuna ve iş kuyruğuna, "task queue", bakar. Eğer hafıza bloğu boşsa, kuyruktaki ilk şeyi alır ve hafıza bloğuna ekler.
bar
çalıştı, "Second"
loglandı ve hafıza bloğundan atıldı.
<div onclick="console.log('first div')">
<div onclick="console.log('second div')">
<button onclick="console.log('button')">
Click!
</button>
</div>
</div>
- A: Dıştaki
div
- B: İçteki
div
- C:
button
- D: İç içe olan tüm elemanlar listesi.
Cevap
Olaya sebep olan en derindeki iç eleman, olayın hedefidir ("event.target"). event.stopPropagation
kullanarak "bubbling"'i durdurabilirsiniz.
<div onclick="console.log('div')">
<p onclick="console.log('p')">
Click here!
</p>
</div>
- A:
p
div
- B:
div
p
- C:
p
- D:
div
Cevap
Eğer p
'ye tıklarsak, iki log görürüz: p
ve div
. Olay silsilesi, "event propagation", sırasında, 3 aşama vardır: "capturing", "target", ve "bubbling". Varsayılan olarak, olay işleyiciler, "event handlers", "bubbling" aşamasında (useCapture
'ı true
olarak ayarlanmadığı müddetçe) çalıştırılır. En derin elemandan dışa doğru gider.
const person = { name: "Lydia" };
function sayHi(age) {
console.log(`${this.name} is ${age}`);
}
sayHi.call(person, 21);
sayHi.bind(person, 21);
- A:
undefined is 21
Lydia is 21
- B:
function
function
- C:
Lydia is 21
Lydia is 21
- D:
Lydia is 21
function
Cevap
İkisinde de, this
anahtar kelimesinin referans olmasını istediğimiz nesneyi geçebiliriz. Ancak, .call
anında çalıştırılır!
.bind.
fonksiyonun kopyasını döndürür, ama konteksle bağlı şejilde. Anında çalıştırılmaz.
function sayHi() {
return (() => 0)();
}
console.log(typeof sayHi());
- A:
"object"
- B:
"number"
- C:
"function"
- D:
"undefined"
Cevap
sayHi
fonksiyonu, anında çalıştırılan fonksiyonun, "immediately invoked function (IIFE)", döndürdüğü değeri döndürür. Bu fonksiyon 0
döndürdü, k, tipi "number"
'dır.
Bilginize; 7 tane tümleşik tip vardır: null
, undefined
, boolean
, number
, string
, object
, ve symbol
. Fonksiyonlar nesne olduklarından, "function"
tip değildir. Fonksiyonun tipi "object"
'dir.
0;
new Number(0);
("");
(" ");
new Boolean(false);
undefined;
- A:
0
,''
,undefined
- B:
0
,new Number(0)
,''
,new Boolean(false)
,undefined
- C:
0
,''
,new Boolean(false)
,undefined
- D: All of them are falsy
Cevap
Sadece 6 tane yanlış-ımsı, "falsy", değer vardır:
undefined
null
NaN
0
''
(empty string)false
Fonksiyon yapıcıları, new Number
ve new Boolean
gibi, doğrusaldır.
console.log(typeof typeof 1);
- A:
"number"
- B:
"string"
- C:
"object"
- D:
"undefined"
const numbers = [1, 2, 3];
numbers[10] = 11;
console.log(numbers);
- A:
[1, 2, 3, 7 x null, 11]
- B:
[1, 2, 3, 11]
- C:
[1, 2, 3, 7 x empty, 11]
- D:
SyntaxError
Cevap
Dizi içinde, dizinin uzunluğunu aşan bir elemana değer atadığınızda, JavaScript "boş alanlar, "empty slots", denilen bir şey oluşturur. Bunların değeri aslında undefined
olsa da şöyle bir şey görürsünüz:
[1, 2, 3, 7 x empty, 11]
nerede çalıştırdığınıza bağlı olarak (her tarayıcı, node, vb... için farklıdır.)
(() => {
let x, y;
try {
throw new Error();
} catch (x) {
(x = 1), (y = 2);
console.log(x);
}
console.log(x);
console.log(y);
})();
- A:
1
undefined
2
- B:
undefined
undefined
undefined
- C:
1
1
2
- D:
1
undefined
undefined
Cevap
catch
bloğu x
argumanını alıyor. Argumanları geçtiğimiz zaman, bu değişken olan x
ile aynı değildir. Bu x
değişkeni block-scoped'dur.
Sonra, bu block-scoped değişkeni 1
'e eşit olarak ayarladık ve y
değişkeninin değerini ayarladık. Block-scoped x
değişkenini logladık, ki değeri 1
'e eşitti.
catch
bloğunun dışında, x
hala undefined
, ve y
2
'dir. catch
bloğunun dışında, console.log(x)
çalıştırmak istediğimizde undefined
döndürür ve y
2
döndürür.
- A: primitifdir ya da nesnedir
- B: fonksiyondur or nesnedir
- C: tuzak soru! sadece nesnedir
- D: sayıdır (number) ya da nesnedir
Cevap
JavaScript sadece primitif ve nesne tiplerine sahiptir.
Primitif tipler, boolean
, null
, undefined
, bigint
, number
, string
, ve symbol
.
Primitif ve nesneyi birbirinden ayıran, primitif tiplerin herhangi bir özelliğie ya da methoda sahip olmamasıdır; ancak, fark edeceğiniz üzere 'foo'.toUpperCase()
'FOO'
olarak değer döndürür ve TypeError
ile sonuçlanmaz. Bunun sebebi, string gibi primitif bir tip üzerinde özelliğe ya da methoda erişmeye çalıştığınızda, JavaScript sarıcı sınıflardan, "wrapper classes", birini kullanarak nesneyi dolaylı şekilde sarar, örneğin String
, ve sonrasında ifade çalıştıktan sonra anında sarıcıyı ayırır. null
ve undefined
dışındaki tüm primitifler bu şekilde davranır.
[[0, 1], [2, 3]].reduce(
(acc, cur) => {
return acc.concat(cur);
},
[1, 2]
);
- A:
[0, 1, 2, 3, 1, 2]
- B:
[6, 1, 2]
- C:
[1, 2, 0, 1, 2, 3]
- D:
[1, 2, 6]
Cevap
[1, 2]
başlangıç değerimizdir. Başladığımız değer budur ve acc
'nin en ilk değeridir. İlk tur süresince, acc
[1,2]
'dir ve cur
[0, 1]
'dir. Onları birleştiririz ve [1, 2, 0, 1]
olarak sonuçlanır.
Sonra, acc
[1, 2, 0, 1]
'dir ve cur
[2, 3]
'dür. Onları birleştiririz ve [1, 2, 0, 1, 2, 3]
elde ederiz.
!!null;
!!"";
!!1;
- A:
false
true
false
- B:
false
false
true
- C:
false
true
true
- D:
true
true
false
Cevap
null
yanlış-ımsıdır, "falsy". !null
true
döndürür. !true
false
döndürür.
""
yanlış-ımsıdır. !""
true
döndürür. !true
false
döndürür.
1
doğrusaldır. !1
false
döndürür. !false
true
döndürür.
setInterval(() => console.log("Hi"), 1000);
- A: benzersiz bir id
- B: belirtilen milisayine tutarı
- C: gönderilen fonksiyon
- D:
undefined
Cevap
Benzersiz bir id döndürür. Bu id, süre aralığını, "interval", clearInterval()
fonksiyonu ile temizlemek için kullanılabilinir.
[..."Lydia"];
- A:
["L", "y", "d", "i", "a"]
- B:
["Lydia"]
- C:
[[], "Lydia"]
- D:
[["L", "y", "d", "i", "a"]]
Cevap
String, yinelenebilirdir, "iterable". Yayma operatörü, yenilenebilirin her bir karakterini bir elemana eşler.
function* generator(i) {
yield i;
yield i * 2;
}
const gen = generator(10);
console.log(gen.next().value);
console.log(gen.next().value);
- A:
[0, 10], [10, 20]
- B:
20, 20
- C:
10, 20
- D:
0, 10 and 10, 20
Cevap
Sıradan fonksiyonlar yürütmenin başlamasının ardından yarı yolda durdurulamaz. Ancak, bir generator fonksiyon yarı yolda "durdurabilir" ve sonra nerede kaldıysa devam edebilir. Bir generator fonksiyon ne zaman yield
anahtar kelimesiyle karşılaşsa, yield'de belirtilen değeri verir. Dikkat edin, generator fonksiyon değeri döndürmez (return), değeri verir (yield).
Önce, generator fonksiyonu i
'yi 10
'a eşitleyerek başlatıyoruz. next()
methodunu kullanarak generator fonksiyonu çalıştırıyoruz. İlk kez generator fonksiyonu çalıştırdığımızda, i
10
'a eşit. Fonksiyon ilk yield
anahtar kelimesi ile karşılaşıyor: i
'nin değerini veriyor. Generatır şimdi "durdu", ve 10
loglandı.
Sonra, next()
methodunu kullanarak fonksiyonu tekrar çalıştırıyoruz. Fonksiyon önceki kaldığı yerden çalışmaya devam ediyor, i
hala 10
'a eşit. Şimdi, fonksiyon sıraki yield
anahtar kelimesi ile karşılaşıyor, ve i * 2
'yi veriyor, yani fonksiyon 10 * 2
veriyor, ki o da 20
'dir. 10, 20
şeklinde sonuçlanıyor.
const firstPromise = new Promise((res, rej) => {
setTimeout(res, 500, "one");
});
const secondPromise = new Promise((res, rej) => {
setTimeout(res, 100, "two");
});
Promise.race([firstPromise, secondPromise]).then(res => console.log(res));
- A:
"one"
- B:
"two"
- C:
"two" "one"
- D:
"one" "two"
Cevap
Promise.race
methoduna birçok promise geçtiğimiz zaman, ilk çözümlenen/reddedilen, "resolves/rejects", promise'i çözümler/reddeder . setTimeout
methoduna, zamanlayıcı, "timer", geçtik: ilk promise (firstPromise
) için 500ms, ve ikinci promise (secondPromise
) için 100ms. Bu demektir ki secondPromise
'two'
değeriyle birlikte önce çözümlenir. res
sakladığı 'two'
değeriyle loglanır.
let person = { name: "Lydia" };
const members = [person];
person = null;
console.log(members);
- A:
null
- B:
[null]
- C:
[{}]
- D:
[{ name: "Lydia" }]
Cevap
Önce, person
değişkenini, name
özelliğine sahip bir nesne değeriyle birlikte tanımlarız.
Sonra, members
olarak adlandırdığımız değişkeni tanımlarız. Bu dizinin ilk elemanını, person
değişkeninin değerine eşit olarak ayarlarız. Nesneler, birbirlerine eşitlendiklerinde, referans üzerinden etkileşime girer. Bir referansı, bir değişkenden diğerine atadığınız zaman, o referansın kopyasını oluşturursunuz. (değişkenlerin aynı referansa sahip olmadığına dikkat edin!)
Sonra, person
değişkenini null
'a eşit olarak ayarlarız.
Sadece person
değişkeninin değerini değiştiriyoruz, dizideki ilk elemanı değil, ilk eleman nesneyi gösteren farklı (kopyalanmış) bir referansa sahip. members
içindeki ilk eleman hala orijinal nesneyi gösteren referansını saklıyor. members
dizisini logladığımız zaman, ilk elemanın hala sakladığı nesnenin değeri loglanır.
const person = {
name: "Lydia",
age: 21
};
for (const item in person) {
console.log(item);
}
- A:
{ name: "Lydia" }, { age: 21 }
- B:
"name", "age"
- C:
"Lydia", 21
- D:
["name", "Lydia"], ["age", 21]
Cevap
for-in
döngüsüyle, nesne keyleri boyunca ileryebiliriz, bu durumda name
ve age
. Temelde, nesne keyleri stringdir (eğer Symbol değilse). Her döngüde, item
'in değerini, döngü sırasındaki geçerli key olarak eşitleriz. Önce, item
name
'e eşittir, ve loglanır. Sonra loglanan item
, age
'e eşittir.
console.log(3 + 4 + "5");
- A:
"345"
- B:
"75"
- C:
12
- D:
"12"
Cevap
Operatör birleşme özelliği, "operator associativity, derleyicinin ifadeleri çalıştırdığı sıradır, ya soldan sağa ya da sağdan soladır. Bu sadece, eğer tüm operatörler aynı önceliğe sahipse gerçekleşir. Sadece tek tip operatörümüz var: +
. Toplama için birleşme özelliği soldan sağadır.
3 + 4
önce çalıştırılır. 7
sayısı olarak sonuçlanır.
Tip baskısından, "coercion", dolayı 7 + '5'
, "75"
olarak sonuçlanır. JavaScript 7
sayısını string'e çevirir, 15. soruya bakabilirsiniz. İki string'i +
operatörünü kullanarak birleştirebiliriz. "7" + "5"
"75"
olarak sonuçlanır.
const num = parseInt("7*6", 10);
- A:
42
- B:
"42"
- C:
7
- D:
NaN
Cevap
Sadece string içindeki ilk sayılar döndürülür. Sayı tabanına (hangi tipte sayıya çözümlemek istediğimizi belirtmek için geçilen ikinci argüman: 10'lu, onaltılı, sekizli, ikili tabanda vb...) bağlı olarak, parseInt
string içindeki hangi karakterlerin geçerli olduğunu kontrol eder. Sayı tabanında, geçerli olmayan bir karaktere denk geldiğinde, çözümleyi durdurur ve sonraki gelen karakterleri görmezden gelir.
*
geçerli bir sayı değil. parseInt
sadece "7"
'yi ondalık sistemde 7
'ye çözümler. num
, 7
değerini saklıyor artık.
[1, 2, 3].map(num => {
if (typeof num === "number") return;
return num * 2;
});
- A:
[]
- B:
[null, null, null]
- C:
[undefined, undefined, undefined]
- D:
[ 3 x empty ]
Cevap
Dizi üzerinde eşleme yaparken, num
'ın değeri, o anda döngüye giren elemanın değerine eşittir. Bu durumda, elemanlar sayı, yani typeof num === "number"
koşul ifadesi true
durdurur. map fonksiyonu yeni bir dizi oluşturur ve fonksiyondan dönen değerleri yerleştirir.
Ancak, biz değer döndürmüyoruz. Bir fonksiyondan değer döndürmediğimiz zaman, fonksiyon undefined
döndürür. Dizideki her eleman için, fonksiyon bloğu çağrılır, yani her bir eleman için undefined
döndürürüz.
function getInfo(member, year) {
member.name = "Lydia";
year = "1998";
}
const person = { name: "Sarah" };
const birthYear = "1997";
getInfo(person, birthYear);
console.log(person, birthYear);
- A:
{ name: "Lydia" }, "1997"
- B:
{ name: "Sarah" }, "1998"
- C:
{ name: "Lydia" }, "1998"
- D:
{ name: "Sarah" }, "1997"
Cevap
Argümanlar değer olarak geçilir, değerleri nesne olmadıkları müddetçe, eğer öyleyse referans olarak geçilir. birthYear
nesne değil string olduğundan değer olarak geçilir. Argümanları değer olarak geçtiğimizde, o değerin bir kopyası oluşturulur (46. soruya göz atın).
birthYear
değişkeni "1997"
değeri için referansa sahip. year
argümanı da ayrıca "1997"
değeri için referansa sahip, ama birthYear
'ın sahip olduğu referansın değeri ile aynı değer değil. year
'ın değerini "1998"
'e eşit olarak ayarlayıp güncellediğimizde, sadece year
'ın değerini güncelleriz. birthYear
hala "1997"
'e eşittir.
person
'ın değeri bir nesnedir. member
argümanı aynı nesne için (kopyalanmış) referansa sahip. member
nesnesinin özelliğini değiştirdiğimizde, person
'ın değeri de ayrıca değişmiş olacaktır, ikisi de aynı nesne için referansa sahip olduklarından. person
'ın name
özelliği şimdi "Lydia"
değerine eşittir.
function greeting() {
throw "Hello world!";
}
function sayHi() {
try {
const data = greeting();
console.log("It worked!", data);
} catch (e) {
console.log("Oh no an error!", e);
}
}
sayHi();
- A:
"It worked! Hello world!"
- B:
"Oh no an error: undefined
- C:
SyntaxError: can only throw Error objects
- D:
"Oh no an error: Hello world!
Cevap
throw
ifadesi ile, özelleştirilmiş hatalar oluşturabiliriz. Bu ifade ile, hatalar fırlatabilirsiniz. Hata durumu, "exception", bir string, sayı, doğru/yanlış ya da nesne olabilir. Bu durumda, bizim hata durumumuz string olan 'Hello world'
.
catch
ifadesi ile, eğer try
bloğunda bir hata durumu fırlatılmışsa ne yapacağımızı belirtebiliriz. Bir hata durumu fırlatıldı: 'Hello world'
string'i. e
artık bu string'e eşit, ki onu logluyoruz. 'Oh an error: Hello world'
olarak sonuç veriyor.
function Car() {
this.make = "Lamborghini";
return { make: "Maserati" };
}
const myCar = new Car();
console.log(myCar.make);
- A:
"Lamborghini"
- B:
"Maserati"
- C:
ReferenceError
- D:
TypeError
Cevap
Bir özellik döndürdüğünüz zaman, özelliğin değeri döndürülen değere eşittir, yapıcı fonksiyon içinde atanmış değere değil. "Maserati"
string'ini döndürüyoruz, yani myCar.make
"Maserati"
'ye eşittir.
(() => {
let x = (y = 10);
})();
console.log(typeof x);
console.log(typeof y);
- A:
"undefined", "number"
- B:
"number", "number"
- C:
"object", "number"
- D:
"number", "undefined"
Cevap
let x = y = 10;
aslında şunun için kısa yazımdır:
y = 10;
let x = y;
y
'yi 10
'a eşit olarak ayarladığımızda, aslında global nesneye y
özelliğini ekliyoruz (tarayıcıda window
, Node içinde global
). Tarayıcıda, window.y
artık 10
'a eşit.
Sonra, x
değişkenini y
'nin değeri ile birlkte tanımlıyoruz ki o da 10
. let
anahtar kelimesi ile tanımlanan değişkenler block scope'dur, onlar sadece tanımlandıkları blok içinde sınırlıdır; bu durumda anında çalıştırılan fonksiyon, "immediately-invoked function (IIFE)", ile sınırlı. typeof
operatörünü kullandığımız zaman, x
operandı tanımlı değil: x
'e tanımlandığı bloğun dışından erişmeye çalışıyoruz. Bu, x
tanımlanmadı demektir. Bir değer ataması yapılmamış ya da tanımlanmamış değerlerin tipi "undefined"
'dır. console.log(typeof x)
"undefined"
döndürür.
Ancak, y
'yi 10
'a eşitlerken global değişken y
'yi oluşturduk. Bu değer kodunuzun herhangi bir yerinden erişilebilinir. y
tanımlı ve "number"
tipinde değeri saklıyor. console.log(typeof y)
"number"
döndürür.
class Dog {
constructor(name) {
this.name = name;
}
}
Dog.prototype.bark = function() {
console.log(`Woof I am ${this.name}`);
};
const pet = new Dog("Mara");
pet.bark();
delete Dog.prototype.bark;
pet.bark();
- A:
"Woof I am Mara"
,TypeError
- B:
"Woof I am Mara"
,"Woof I am Mara"
- C:
"Woof I am Mara"
,undefined
- D:
TypeError
,TypeError
Cevap
delete
anahtar kelimesini kullanarak özellikleri hem nesnelerden hem de prototip üzerinden silebiliriz. Prototip üzerindeki bir özellik silindiğinde, artık prototip zincirinde kullanıma müsait değildir. Bu durumda, bark
fonksiyonu, delete Dog.prototype.bark
ardından, prototip üzerinden kullanılabilir değildir fakat yine de erişmeye çalışıyoruz.
Fonksiyon olmayan bir şeyi çalıştırmayı denediğimiz zaman, TypeError
fırlatılır. Bu durumda, pet.bark
undefined
olduğundan, TypeError: pet.bark is not a function
fırlatıldı.
const set = new Set([1, 1, 2, 3, 4]);
console.log(set);
- A:
[1, 1, 2, 3, 4]
- B:
[1, 2, 3, 4]
- C:
{1, 1, 2, 3, 4}
- D:
{1, 2, 3, 4}
Cevap
Set
nesnesi benzersiz değerlerin koleksiyonudur: bir değer, set içinde sadece bir kez bulunabilir.
Yinelenebilir [1, 1, 2, 3, 4]
'i çift 1
değeriyle birlikte geçtik. Set içinde aynı değere iki kere sahip olamayacağımızdan, bir tanesi kaldırıldı. Sonuç, {1, 2, 3, 4}
.
// counter.js
let counter = 10;
export default counter;
// index.js
import myCounter from "./counter";
myCounter += 1;
console.log(myCounter);
- A:
10
- B:
11
- C:
Error
- D:
NaN
Cevap
İçe aktarılan, "imported", modul salt okur'dur: içe aktarılan modulü değiştiremezsiniz. Sadece, dışa aktarım yapan modul değerini değiştirebilir.
myCounter
'ın değerini arttırmaya çalıştığımız zaman, hata fırlatır: myCounter
salt okurdur ve değiştirilemez.
const name = "Lydia";
age = 21;
console.log(delete name);
console.log(delete age);
- A:
false
,true
- B:
"Lydia"
,21
- C:
true
,true
- D:
undefined
,undefined
Cevap
delete
operatörü doğru/yanlış, "boolean", değer döndürür: silme başarılıysa true
, değilse false
döndürecektir. Ancak, var
, const
ya da let
anahtar kelimeleri ile tanımlanan değişkenler, delete
kullanılarak silinemez.
name
değişkeni const
anahtar kelimesi ile tanımlandı, yani silinme işlemi başarılı değil: false
döndü. age
'i 21
'e eşitlediğimizde, global nesneye age
diye özellik ekledik aslında. Bu yöntemle, sorunsuz şekilde nesnelerden özellikleri silebilirsiniz, böylelikle delete age
true
döndürür.
const numbers = [1, 2, 3, 4, 5];
const [y] = numbers;
console.log(y);
- A:
[[1, 2, 3, 4, 5]]
- B:
[1, 2, 3, 4, 5]
- C:
1
- D:
[1]
Cevap
Listelerden değerleri ya da nesnelerden özellikleri, yıkım yoluyla, "destructuring", çıkarabiliriz. Örneğin:
[a, b] = [1, 2];
a
'nın değeri 1
ve b
'nin değeri 2
'dir. Bu soruda aslında yaptığımız şuydu:
[y] = [1, 2, 3, 4, 5];
Bu demektir ki, y
'nin değeri dizideki ilk değere eşit, o da 1
sayısıdır. y
'yi logladığımız zaman, 1
döndürülür.
const user = { name: "Lydia", age: 21 };
const admin = { admin: true, ...user };
console.log(admin);
- A:
{ admin: true, user: { name: "Lydia", age: 21 } }
- B:
{ admin: true, name: "Lydia", age: 21 }
- C:
{ admin: true, user: ["Lydia", 21] }
- D:
{ admin: true }
Cevap
Nesneleri ...
yayma operatörü kullanarak birleştirmek, kombine etmek, mümkündür. Bir nesnenin key/değer kopyasını oluşturmanıza olanak sunar, ve key/değerleri diğer nesneye ekler. Bu durumda, user
nesnesinin kopyasını oluşturuyoruz, ve onları admin
nesnesine ekliyoruz. admin
nesnesi şimdi kopyalanan key/değerleri de içeriyor, ki bu da { admin: true, name: "Lydia", age: 21 }
olarak sonuç verir.
const person = { name: "Lydia" };
Object.defineProperty(person, "age", { value: 21 });
console.log(person);
console.log(Object.keys(person));
- A:
{ name: "Lydia", age: 21 }
,["name", "age"]
- B:
{ name: "Lydia", age: 21 }
,["name"]
- C:
{ name: "Lydia"}
,["name", "age"]
- D:
{ name: "Lydia"}
,["age"]
Cevap
defineProperty
methodu ile, nesnelere yeni özellikler ekleyebiliriz, ya da var olanları değiştirebiliriz. defineProperty
methodu kullanarak bir nesneye özellik eklediğimiz zaman, varsayılan olarak sıralanabilir değildir, "not enumerable". Object.keys
methodu, bir nesneden tüm sıralanabilir özelliklerin adını döndürür, bu durumda sadece "name"
.
defineProperty
methodu kullanılarak eklenen özellikler, varsayılan olarak değişmezdir. Bu davranışı writable
, configurable
ve enumerable
kullaranak ezebilirsiniz. Bu yöntemle, defineProperty
methodu nesnelere eklediğiniz özellikler üzerinde size çok daha fazla kontrol verir.
const settings = {
username: "lydiahallie",
level: 19,
health: 90
};
const data = JSON.stringify(settings, ["level", "health"]);
console.log(data);
- A:
"{"level":19, "health":90}"
- B:
"{"username": "lydiahallie"}"
- C:
"["level", "health"]"
- D:
"{"username": "lydiahallie", "level":19, "health":90}"
Cevap
JSON.stringify
'ın ikinci argumanı değiştiricidir, "replacer". Değiştirici bir fonksiyon ya da bir dizi olabilir, ve değerlerin hangilerinin ve nasıl string'e dönüşeceğini kontrol etmenize izin verir.
Eğer değiştirici dizi ise, sadece dizi içinde ismi geçem özellikler JSON string'e dahil edilmiş olur. Bu durumda, sadece "level"
ve "health"
isimli özellikler dahil edildi, "username"
dışarıda bırakıldı. data
, "{"level":19, "health":90}"
eşittir.
Eğer değiştirici fonksiyon ise, stringe dönüştürülen her özellik için bu fonksiyon çağrılır. Bu fonksiyondan dönen değer, JSON stringe eklenmiş olacak özelliğin değeri olacaktır. Eğer değer undefined
'sa, bu özellik JSON stringe dahil edilmez.
let num = 10;
const increaseNumber = () => num++;
const increasePassedNumber = number => number++;
const num1 = increaseNumber();
const num2 = increasePassedNumber(num1);
console.log(num1);
console.log(num2);
- A:
10
,10
- B:
10
,11
- C:
11
,11
- D:
11
,12
Cevap
++
unary operatörü önce operandın değerini döndürür, sonra operandın değerini arttırır. increaseNumber
fonksiyonu önce değeri 10
olan num
'ın değerini döndürdüğünden, num1
'ın değeri 10
'dur, ve num
'ın değeri ancak bundan sonra artar.
increasePassedNumber
'a num1
'i geçtiğimizden, num2
'nin değeri 10
'dur. number
10
'a eşittir (num1
'ın değeri. Bir kez daha, ++
operatörü önce operandın değerini döndürür, sonra operandın değerini arttırır. number
'ın değeri 10
, yani num2
10
'a eşittir.)
const value = { number: 10 };
const multiply = (x = { ...value }) => {
console.log((x.number * 2));
};
multiply();
multiply();
multiply(value);
multiply(value);
- A:
20
,40
,80
,160
- B:
20
,40
,20
,40
- C:
20
,20
,20
,40
- D:
NaN
,NaN
,20
,40
Cevap
ES6'da, parametrelere varsayılan değer atayabiliriz. Eğer fonksiyona değer geçilmezse ya da parametrenin değeri undefined
ise, parametrenin değeri varsayılan değer olacaktır. Bu örnekte, value
nesnesinin özelliklerini yeni nesneye yaydık, böylece x
varsayılan değer olarak { number: 10}
'a sahip.
Varsayılan argüman çağrı sırasında, "call time", çalıştırılır. Fonksiyonu her çağırdığımızda, yeni bir nesne oluşturulur. multiply
fonksiyonunu ilk iki seferde değer geçmeden çağırdık: x
varsayılan değeri olan { number: 10 }
'a sahip. Sonra, bu sayının çarpılmış değerini logluyoruz, o da 20
.
Üçüncü kez, multiply
'ı çağırdığımız zaman, argüman geçiyoruz: value
isimli nesne. *=
operatörü aslında x.number = x.number * 2
için kısa yazımdır: x.number
'ın değerini değiştiriyoruz ve çarpılmış değer olan 20
'yi logluyoruz.
Dördüncü kez, value
nesnesini tekrar geçiyoruz. x.number
önceden 20
'ye değiştirilmişti, yani x.number *= 2
40
loglar.
[1, 2, 3, 4].reduce((x, y) => console.log(x, y));
- A:
1
2
and3
3
and6
4
- B:
1
2
and2
3
and3
4
- C:
1
undefined
and2
undefined
and3
undefined
and4
undefined
- D:
1
2
andundefined
3
andundefined
4
Cevap
reduce
methodunun aldığı ilk argüman biriktiricidir, "accumulator", bu örnekte x
. İkinci argüman o anki değerdir, y
. reduce methodu ile, dizideki her eleman üzerinde callback fonksiyonunu çalıştırırız, bu da en sonunda tek bir değer sonuçlanabilir.
Bu örnekte, geriye bir değer döndürmüyoruz, sadece biriktiricinin değerini ve o anki değeri logluyoruz.
Biriktiricinin değeri, bir önceki callback fonksiyonunun dönen değerine eşittir. Eğer, opsiyonel olan initialValue
agümanını reduce
methoduna geçmezseniz, biriktiricinin değeri, ilk çağrılışta gelen elemana eşit olur.
İlk çağrılışta, biriktirici (x
) 1
'dir, ve y
'nin o anki değeri 2
'dir. callback fonksiyonundan bir şey döndürmüyoruz, biriktiriciyi ve o anki değeri logluyoruz: 1
ve 2
loglanır.
Eğer bir fonksiyondan değer döndürmezseniz, fonksiyon undefined
döndürür. Sonraki çağrılışta, biriktirici undefined
, ve o anki geçerli değer 3
'tür. undefined
ve 3
loglanır.
Dördündü çağrıda, tekrar callback fonksiyonundan değer döndürmüyoruz. Biriktirici tekrar undefined
, ve o anki geçerli değer 4
. undefined
ve 4
loglanır.
class Dog {
constructor(name) {
this.name = name;
}
};
class Labrador extends Dog {
// 1
constructor(name, size) {
this.size = size;
}
// 2
constructor(name, size) {
super(name);
this.size = size;
}
// 3
constructor(size) {
super(name);
this.size = size;
}
// 4
constructor(name, size) {
this.name = name;
this.size = size;
}
};
- A: 1
- B: 2
- C: 3
- D: 4
Cevap
Türetilmiş bir sınıfta, super
'i çağırmadan önce this
anahtar kelimesine erişemezsiniz. Eğer erişmeyi denerseniz, ReferenceError fırlatır: 1 ve 4 referans hatası fırlatır.
super
anahtar kelimesiyle, parent sınıfın yapıcı methodunu verilen argümanlarla beraber çağırırız. Parent sınıfın yapıcısı name
argümanını alıyor, bu yüzden super
'e name
'i vermemiz gerek.
Dog
sınıfı iki argüman alıyor, name
Animal
sınıfından türediğinden, ve size
Dog
sınıfı üzerinde ekstra özellik olarak. İkisinin de Dog
yapıcı methoduna geçilmesi gerek, bu da 2. yapıcı methodda doğru şekilde kullanılarak yapılmıştır.
// index.js
console.log('running index.js');
import { sum } from './sum.js';
console.log(sum(1, 2));
// sum.js
console.log('running sum.js');
export const sum = (a, b) => a + b;
- A:
running index.js
,running sum.js
,3
- B:
running sum.js
,running index.js
,3
- C:
running sum.js
,3
,running index.js
- D:
running index.js
,undefined
,running sum.js
Cevap
import
anahtar kelimesiyle, tüm içe aktarılan modüller ilk çözümlenir, "pre-parsed". Bu şu demektir, içe aktarılan modüller önce çalışır, içe aktarım yapan dosyadaki kodlar sonra çalıştırılır.
CommonJS'deki require()
ve import
arasındaki fark budur! require()
ile, bağımlılıkları kod çalışmaya başladığında yükleyebilirsiniz. import
yerine require
kullanmış olsaydık, running index.js
, running sum.js
, 3
konsolda loglanmış olacaktı.
console.log(Number(2) === Number(2))
console.log(Boolean(false) === Boolean(false))
console.log(Symbol('foo') === Symbol('foo'))
- A:
true
,true
,false
- B:
false
,true
,false
- C:
true
,false
,true
- D:
true
,true
,true
Cevap
Her Symbol tamamen benzersizdir. Symbol'e geçilen argümanın amacı, Symbol'e bir açıklama vermektir. Symbol'ün değeri geçilen argümana bağlı değildir. Eşitliği test ederken, tamamen yeni iki symbol oluşturuyoruz: ilki Symbol('foo')
ve ikincisi Symbol('foo')
. Bu iki değer benzersiz ve birbirlerine eşit değil, Symbol('foo') === Symbol('foo')
false
döndürür.
const name = "Lydia Hallie"
console.log(name.padStart(13))
console.log(name.padStart(2))
- A:
"Lydia Hallie"
,"Lydia Hallie"
- B:
" Lydia Hallie"
," Lydia Hallie"
("[13x whitespace]Lydia Hallie"
,"[2x whitespace]Lydia Hallie"
) - C:
" Lydia Hallie"
,"Lydia Hallie"
("[1x whitespace]Lydia Hallie"
,"Lydia Hallie"
) - D:
"Lydia Hallie"
,"Lyd"
,
Cevap
padStart
methoduyla, bir string'in başlangıcına dolgu yapabiliriz. Bu methoda geçilen değer, dolguyla beraber string'in toplam uzunluğudur. "Lydia Hallie"
'in uzunluğu 12
, name.padStart(13)
string'in başlangıcına 1 boşluk eker, çünkü 12 + 1 = 13.
Eğer padStart
methoduna geçilen argüman, string'in uzunluğundan daha azsa, dolgu yapılmaz.
console.log("🥑" + "💻");
- A:
"🥑💻"
- B:
257548
- C: A string containing their code points
- D: Error
Cevap
+
operatörü ile stringleri birleştirebilirsiniz. Bu örnekte, "🥑"
ile "💻"
birleştiriyoruz, "🥑💻"
olarak sonuçlanıyor.
function* startGame() {
const answer = yield "Do you love JavaScript?";
if (answer !== "Yes") {
return "Oh wow... Guess we're gone here";
}
return "JavaScript loves you back ❤️";
}
const game = startGame();
console.log(/* 1 */); // Do you love JavaScript?
console.log(/* 2 */); // JavaScript loves you back ❤️
- A:
game.next("Yes").value
andgame.next().value
- B:
game.next.value("Yes")
andgame.next.value()
- C:
game.next().value
andgame.next("Yes").value
- D:
game.next.value()
andgame.next.value("Yes")
Cevap
Generator fonksiyon yield
anahtar kelimesini gördüğünde çalışmasını "durdurur". Öncelikle, fonksiyonun "Do you love JavaScript?" stringini vermesini sağlamamız gerek ki bu game.next().value
çağrılarak yapılabilir.
İlk yield
anahtar kelimesi bulunana dek her satır çalıştırılır. Fonksiyonun içinde, ilk satırda yield
anahtar kelimesi var: çalışma ilk yield ile durur. Bu demektir ki answer
değişkeni henüz tanımlanmadı!
game.next("Yes").value
çağırdığımız zaman, önceki yield
next()
fonksiyonuna geçilen parametlerin değeri ile değiştirilir, bu durumda "Yes"
. answer
değişkeninin değeri artık "Yes"
'e eşit. if ifadesi false
döndürür, ve JavaScript loves you back ❤️
loglanır.
console.log(String.raw`Hello\nworld`);
- A:
Hello world!
- B:
Hello
world
- C:
Hello\nworld
- D:
Hello\n
world
Cevap
String.raw
kaçış karakterlerinin (\n
, \v
, \t
vb.) göz ardı edildiği bir string döndürür. Ters bölü işareti şöyle bir şey gibi sonuçlanabileceğinden sorun olabilir:
const path = `C:\Documents\Projects\table.html`
Şöyle sonuçlanır:
"C:DocumentsProjects able.html"
String.raw
ile, kaçış karakteri basitçe göz ardı edilir ve yazdırılır:
C:\Documents\Projects\table.html
Bu örnekte, string Hello\nworld
, dolayısıyla Hello\nworld
olarak loglanır.
async function getData() {
return await Promise.resolve("I made it!");
}
const data = getData();
console.log(data);
- A:
"I made it!"
- B:
Promise {<resolved>: "I made it!"}
- C:
Promise {<pending>}
- D:
undefined
Cevap
Asenkron bir fonksiyon her zaman promise döndürür. await
promise'ı çözmek için beklemeli: getData()
'yı data
'ya eşitlemek için çağırdığımız zaman bekleyen promise döndürülür.
Çözülmüş değer olan "I made it"
'e erişmek isteseydik, data
üzerinde .then()
methodunu kullanabilirdik:
data.then(res => console.log(res))
Bu "I made it!"
loglardı.
function addToList(item, list) {
return list.push(item);
}
const result = addToList("apple", ["banana"]);
console.log(result);
- A:
['apple', 'banana']
- B:
2
- C:
true
- D:
undefined
Cevap
push()
methodu yeni dizinin uzunluğunu döndürür. Önceden, dizi bir eleman içeriyordu ("banana"
) ve uzunluğu 1'di. Diziye "apple"
'ı ekledikten sonra, dizi iki eleman içerir ve uzunluğu 2
'dir. addToList
fonksiyonundan döndürülen budur.
push
methodu orijinal diziyi değiştirir. Eğer dizinin uzunluğunu değil de diziyi döndürmek isterseniz, item
'i ekledikten sonra list
'i döndürmelisiniz.
const box = { x: 10, y: 20 };
Object.freeze(box);
const shape = box;
shape.x = 100;
- A:
{ x: 100, y: 20 }
- B:
{ x: 10, y: 20 }
- C:
{ x: 100 }
- D:
ReferenceError
Cevap
Object.freeze
bir nesneye özellik eklemeyi, silmeyi ya da değiştirmeyi olanaksız kılar (özelliğin değeri başka bir nesneye ait olmadıkça)
shape
değişkenini oluşturup, donmuş box
nesnesine eşitlediğimiz zaman, shape
de ayrıca donmuş nesneyi referans eder. Object.isFrozen
kullanarak bir nesnenin dondurulmuş olup olmadığını kontrol edebilirsiniz. Bu örnekte, shape
değişkeni donmuş bir nesneyi referans gösterdiğinden, Object.isFrozen(shape)
true
döndürür.
shape
donmuş olduğundan, ve x
'in değeri bir nesne olmadığından, x
özelliğini değiştiremeyiz. x
hala 10
'a eşit, ve { x: 10, y: 20 }
loglanır.
const { name: myName } = { name: "Lydia" };
console.log(name);
- A:
"Lydia"
- B:
"myName"
- C:
undefined
- D:
ReferenceError
Cevap
Eşitliğin sağ tarafındaki nesneden name
özelliğini çıkarttığımız zaman, myName
isimli değişkene, o özelliğin değeri olan "Lydia"
'yı atıyoruz.
{ name: myName }
ile, JavaScript'e diyoruz ki; eşitliğin sağ tarafındaki name
özelliğinin değeriyle birlikte myName
diye bir değişken tanımlamak istiyoruz.
name
'i loglamayı denediğimizden dolayı, ki bu değişken tanımlanmamış, ReferenceError fırlatılır.
function sum(a, b) {
return a + b;
}
- A: Yes
- B: No
Cevap
Saf fonksiyon, aynı argümanlar geçildiği zaman, her zaman aynı sonucu döndüren fonksiyondur.
sum
fonksiyonu her zaman aynı sonucu döndürür. Eğer 1
ve 2
geçersek, her zaman 3
döndürecektir. Eğer 5
ve 10
geçersek, her zaman 15
döndürür, bunun gibi devam eder... Saf fonksiyonun tanımlaması budur.
const add = () => {
const cache = {};
return num => {
if (num in cache) {
return `From cache! ${cache[num]}`;
} else {
const result = num + 10;
cache[num] = result;
return `Calculated! ${result}`;
}
};
};
const addFunction = add();
console.log(addFunction(10));
console.log(addFunction(10));
console.log(addFunction(5 * 2));
- A:
Calculated! 20
Calculated! 20
Calculated! 20
- B:
Calculated! 20
From cache! 20
Calculated! 20
- C:
Calculated! 20
From cache! 20
From cache! 20
- D:
Calculated! 20
From cache! 20
Error
Cevap
add
fonksiyonu ezberlenmiş, "memoized", bir fonksiyondur. Ezberleme ile, fonksiyonun sonuçlarını, fonksiyonun daha hızlı çalışması için cache'leyebiliriz. Bu örnekte, önceki dönen değerleri saklayan bir cache
nesnesi oluşturuyoruz.
Eğer addFunction
fonksiyonunu aynı argüman ile tekrar çağırırsak, önce cache içinde o değerin hali hazırda olup olmadığını kontrol eder. Eğer varsa, cache değeri döndürülecektir ki böylece çalışma zamanından tasarruf sağlanır. Eğer yoksa, cache'lenmemişse, değeri hesaplayıp ardından saklayacaktır.
addFunction
fonksiyonunu üç kez aynı değer ile çağırıyoruz: ilk çağırmada, num
10
'a eşit olduğu zaman fonksiyonun değeri henüz cache'lenmemiş. num in cache
if ifadesi false
döndürür
ve else bloğu çalıştırılır: Calculated! 20
loglanır, ve sonuç cache nesnesine eklenir. cache
şimdi şuna benziyor; { 10: 20 }
İkincide, cache
nesnesi 10
için döndürülen değeri içeriyor. num in cache
if ifadesi true
döndürür, ve 'From cache! 20'
loglanır.
Üçüncü sefer de, fonksiyona 5 * 2
geçiyoruz ki bu da 10
olarak değerlendirilir. cache
nesnesi 10
için döndürülen değeri içeriyor. num in cache
if ifadesi true
döndürür, ve 'From cache! 20'
loglanır.