JavaScript'te == kullanmak hiç mantıklı geliyor mu?


276

In JavaScript, İyi Parçaları Douglas Crockford yazdı:

JavaScript'in iki eşitlik operatörü vardır: ===ve !==, ve onların kötü ikizleri ==ve !=. İyi olanlar beklediğiniz gibi çalışır. İki işlenen aynı türde ve aynı değere sahipse, o zaman ===üretir trueve !==üretir false. Kötü ikizler, operandlar aynı tip olduğunda doğru olanı yaparlar, ancak farklı tiplerdeyse değerleri zorlamaya çalışırlar. Bunu yaptıkları kurallar karmaşık ve unutulmazdır. Bunlar ilginç durumlardan bazıları:

'' == '0'           // false
0 == ''             // true
0 == '0'            // true

false == 'false'    // false
false == '0'        // true

false == undefined  // false
false == null       // false
null == undefined   // true

' \t\r\n ' == 0     // true

Geçiş eksikliği endişe verici. Tavsiyem asla kötü ikizleri kullanmamak. Bunun yerine, her zaman ===ve kullanın !==. Az önce gösterilen karşılaştırmaların tümü operatörle falsebirlikte ===üretilir.

Bu kesin gözlem yapıldığında, kullanımın ==gerçekten uygun olabileceği bir zaman var mı?


11
Bu mantıklı yerlerde bir sürü. Ne zaman aynı tipte iki şeyi karşılaştırdığın açıkça belli oluyorsa (bu benim deneyimimde çok olur), == vs === sadece tercihe bağlı. Diğer zamanlarda gerçekten soyut bir karşılaştırma yapmak istersiniz (cevabınızda bahsettiğiniz gibi). Uygun olup olmadığı , herhangi bir proje için sözleşmelere bağlıdır.
Hey,

4
"Çok fazla yer" ile ilgili olarak, deneyimlerime göre, önemsiz olduğu durumlarda, yaptığı dava sayısından fazla değildir. Deneyiminiz farklı olabilir; belki de farklı projelerle deneyime sahibiz. ==Varsayılan olarak kullanılan projelere baktığımda ===göze çarpıyor ve önemli bir şeyin olup bittiğini bilmeme izin veriyor.
Hey

4
JavaScript'in zorlama konusunda yeterince ileri gittiğini sanmıyorum. Tıpkı BS dili gibi daha zorlayıcı baskı seçeneklerine sahip olması gerekir .
Mark Booth,

5
Kullandığım tek yer ==, açılır kimlikleri (her zaman char olan) model kimliğiyle (genellikle int'dir) karşılaştırırken.
Scottie,

12
@DevSolar Web geliştirme, 15 platformun her biri için yerel bir uygulama üretmekle uğraşmak istemediğinizde, bir platformun tekel App Store'unda sertifikalandırma yapmak istemediğiniz zaman anlamlıdır.
Damian Yerrick

Yanıtlar:


232

İçin bir tartışma yapacağım ==

Aldığın Douglas Crockford, çok ve çoğu zaman çok yararlı görüşleri ile bilinir. Crockford ile bu özel durumdayken, tek fikir olmadığını söylemeye değer . Büyük sorunu görmeyen dil yaratıcısı Brendan Eich gibi başkaları da var ==. Argüman aşağıdaki gibi biraz gider:

JavaScript davranışsal olarak * yazılmış bir dildir. Her şeye, yapabileceklerine göre değil, gerçek türlerine göre muamele edilir. Bu yüzden .mapbir NodeList'te veya bir jQuery seçim setinde bir dizinin yöntemini çağırabilirsiniz . Aynı zamanda 3 - "5"anlamlı bir şey yapmanın ve geri kazanmanın da nedeni budur - çünkü "5" sayı gibi davranabilir.

Bir gerçekleştirdiğinizde ==eşitliği karşılaştırdığınız olan içerikleri ziyade onun daha değişkenin türü . İşte bu yararlı olduğu bazı durumlar:

  • Kullanıcıdan bir numara okumak - DOM'daki .valuebir giriş elemanını okumak ? Sorun değil! Döküm yapmaya veya türüyle ilgili endişelenmeye başlamak zorunda değilsiniz - ==hemen sayılara ulaşabilir ve anlamlı bir şey elde edebilirsiniz.
  • Bildirilen bir değişkenin "varlığını" kontrol etmeniz mi gerekiyor? - == nullDavranışsal olarak nullorada hiçbir şey olmadığını ve tanımlanamayanların da orada hiçbir şey olmadığını temsil ettiği için yapabilirsiniz .
  • Bir kullanıcıdan anlamlı bir giriş olup olmadığını kontrol etmeniz mi gerekiyor? - Girişin ==argümanla yanlış olup olmadığını kontrol edin , kullanıcının sizin için hiçbir şey girmediği durumları veya sadece sizin için beyaz boşlukları kullanacağını düşünecektir.

Crockford'un örneklerine bakalım ve bunları davranışsal olarak açıklayalım:

'' == '0'           // got input from user vs. didn't get input - so false
0 == ''             // number representing empty and string representing empty - so true
0 == '0'            // these both behave as the number 0 when added to numbers - so true    
false == 'false'    // false vs got input from user which is truthy - so false
false == '0'        // both can substitute for 0 as numbers - so again true

false == undefined  // having nothing is not the same as having a false value - so false
false == null       // having empty is not the same as having a false value - so false
null == undefined   // both don't represent a value - so true

' \t\r\n ' == 0     // didn't get meaningful input from user vs falsey number - true 

Temelde, ==ilkel şekline göre çalışır şekilde tasarlanmıştır davranmaları onlar neyi dayanmayan JavaScript vardır . Bu bakış açısına şahsen katılmıyorum, ancak bunu yapmanın kesinlikle yararı var - özellikle de, dil genelindeki davranışa dayalı bu tür muamele paradigmasını kullanıyorsanız.

* bazıları daha yaygın olan yapısal yazım adını tercih edebilir, ancak bir fark var - buradaki farkı tartışmakla ilgilenmiyor.


8
Bu harika bir cevap ve ben de 'for ==' kullanım durumlarınızın üçünü de kullanıyorum. # 1 & # 3 özellikle kullanışlıdır.
Chris Cirefice,

224
Sorun ==, kıyaslamaların hiçbirinin işe yaramaması değil, kuralların hatırlanması imkansız olması değil, bu yüzden neredeyse hata yapma garantisi veriyorsunuzdur. Örneğin: "Bir kullanıcıdan anlamlı bir giriş olup olmadığını kontrol etmeniz mi gerekiyor?", Ancak '0' anlamlı bir giriş ve '0'==falsedoğrudur. Kullanmış olsaydın, ===açıkça bunu düşünmek zorunda kalırdın ve hata yapmazdın.
Timmmm

44
"kuralların hatırlanması imkansız" <== bu, Javascript'te "anlamlı" bir şey yapmamdan korkan şey. (ve temel kireç alıştırmalarında sorunlara yol açan matematik yüzer)
WernerCD

9
3 - "5"Örnek kendi başına iyi bir noktaya yükseltir: Yalnızca kullanmak bile ===karşılaştırma için, bu değişkenler JavaScript çalışmak sadece yoludur. Tamamen kaçmanın yolu yok.
Jarett Millard,

23
@Timmmm not burada şeytanın avukatı oynuyorum. ==Kendi kodumda kullanmıyorum , onu bir kalıp karşıtı buluyorum ve soyut eşitlik algoritmasının hatırlamak zor olduğuna tamamen katılıyorum. Burada yaptığım, insanların bunun için yaptıkları tartışmayı yapmak.
Benjamin Gruenbaum

95

JQuery'nin yapıyı kullandığı ortaya çıktı

if (someObj == null) {
  // do something
}

yaygın olarak, eşdeğer kod için bir kısa yol olarak:

if ((someObj === undefined) || (someObj === null))  {
  // do something
}

Bu, ECMAScript Dil Belirtimi § 11.9.3'ün, diğer şeylerin yanı sıra, bunu belirten Soyut Eşitlik Karşılaştırma Algoritmasının bir sonucudur.

1.  If Type(x) is the same as Type(y), then  
    a.  If Type(x) is Undefined, return true.  
    b.  If Type(x) is Null, return true.

ve

2.  If x is null and y is undefined, return true.
3.  If x is undefined and y is null, return true.

Bu özel teknik, JSHint'in kendisi için özel olarak tasarlanmış bir bayrağa sahip olması yeterince yaygındır .


10
Bu :) cevap istedi Kendi soruya cevap yok adil == null or undefinedben kullanmıyorum tek yer ===veya!==
pllee

26
Adil olmak gerekirse, jQuery pek bir model kod temeli değildir. JQuery kaynağını birkaç kez okuduktan sonra, birçok iç içe geçmiş üçlü, belirsiz bit, iç içe geçmiş ve gerçek kodda sakınacağım şeylerle en sevdiğim kod tabanlarımdan biri. Yine de benim sözümü almayın - github.com/jquery/jquery/tree/master/src adresini okuyun ve ardından bir jQuery klonu olan Zepto ile karşılaştırın: github.com/madrobby/zepto/tree/master/src
Benjamin Gruenbaum

4
Ayrıca, Zepto’nun varsayılan olarak göründüğünü ==ve yalnızca gerektiğinde kullandığını unutmayın ===: github.com/madrobby/zepto/blob/master/src/event.js
Hey

2
Dürüst olmak gerekirse: Zepto, pek de bir model kod temeli değil - __proto__mobil web sitelerini kırmamak için neredeyse tek bir dil belirtiminde kullanmak için ve sırayla zorlamak için rezil .
Benjamin Gruenbaum

2
@BenjaminGruenbaum, kod tabanlarının kalitesine dair bir yargılama çağrısı değildi, sadece farklı projelerin farklı sözleşmeler izlediğini belirtti.
Hey,

15

Değerleri kontrol etmek nullya undefinedda bol miktarda açıklandığı gibi bir şey var.

==Parlayan başka bir şey var :

Karşılaştırma yöntemini şöyle tanımlayabilirsiniz >=(insanlar genellikle başlar >ama ben bunu daha şık buluyorum):

  • a > b <=> a >= b && !(b >= a)
  • a == b <=> a >= b && b >= a
  • a < bve a <= bokuyucuya bir egzersiz olarak bırakılmıştır.

Bildiğimiz gibi, JavaScript’te "3" >= 3ve "3" <= 3hangisinden aldığınızı 3 == "3". Dizeyi ayrıştırıp dizelerle sayılar arasında karşılaştırma yapılmasına izin vermenin korkunç bir fikir olduğuna işaret edebilirsiniz. Ama bu işler böyle olduğu göz önüne alındığında, ==kesinlikle olduğunu bu ilişki operatörü uygulamak için doğru yolu.

Bu yüzden gerçekten iyi olan şey ==, diğer tüm ilişkilerle tutarlı olması. Bunu farklı şekilde söylemek gerekirse, şunu yazarsanız:

function compare(a, b) {
  if (a > b) return 1;
  if (a < b) return -1;
  return 0;
}

Örtülü olarak ==zaten kullanıyorsunuz .

Şimdi oldukça ilgili bir soruya: Sayı ve dizi karşılaştırmasını uygulandığı şekilde uygulamak kötü bir seçim miydi? İzolasyonda görüldüğü zaman yapmak aptalca bir şey. Ancak, JavaScript ve DOM’un diğer bölümleri bağlamında, aşağıdakileri göz önünde bulundurarak nispeten pratiktir:

  • öznitelikler her zaman dizgedir
  • tuşları her zaman dizgedir (kullanım durumu Object, bir ints'ten değerlere kadar seyrek bir haritaya sahip olmanız için kullanılır )
  • kullanıcı girişi ve form kontrol değerleri her zaman dizgedir (kaynak eşleşse bile input[type=number])

Bir dizi nedenden dolayı, dizgelerin gerektiğinde sayılar gibi davranmasını sağlamak mantıklıydı. Ve dize karşılaştırması ve dize birleştirme işleminin farklı işleçleri olduğunu varsayarsak (örneğin ::, birleştirme için ve bir karşılaştırma yöntemi (büyük / küçük harf duyarlılığı ile ilgili her türlü parametreyi nerede kullanabileceğinizi)), bu aslında biraz daha karışık olur. Ancak bu operatör aşırı yüklemesi muhtemelen "JavaScript" deki "Java" nın geldiği yer;


4
Adil olmak >=gerçekten geçişli değil. Ne JS ne a > bde a < bne de b == a(örneğin :) oldukça mümkün NaN.
Benjamin Gruenbaum

8
@BenjaminGruenbaum: Bu +demek oluyor ki gerçekten değişmeli değil, çünkü NaN + 5 == NaN + 5geçerli değil. Mesele şu ki, sürekli >=çalışan, sayı-ish değerleriyle ==çalışıyor. “Sayı değil” in doğası gereği sayı-ish değil olması şaşırtıcı değildir;)
back2dos

4
Yani zayıf davranış, zayıf davranışla ==tutarlı >=mı? Harika, şimdi keşke bir keşke olsaydı >==...
Eldritch Conundrum

2
@EldritchConundrum: Açıklamaya çalıştığım gibi, davranışı >=dilin / standart API'lerin geri kalanıyla oldukça tutarlıdır. Bütünlüğü içinde, JavaScript ilginç bölümlerinin toplamından daha fazlası olmayı başarır. İsterseniz >==, sıkı bir de ister misiniz +? Uygulamada, bu kararların çoğu birçok şeyi çok daha kolay hale getirir. Bu yüzden onları fakir olarak değerlendirmek için acele etmem.
back2dos,

2
@EldritchConundrum: Yine: ilişki işleçleri, bir işlenenin gerçekte bir dize olabileceği sayısal değerleri karşılaştırmak içindir. >=Anlamlı olan işlenen türleri için ==eşit derecede anlamlı - hepsi bu. Kimse karşılaştırmak gerektiğini söylüyor [[]]ile false. C gibi dillerde, bu saçmalık seviyesinin sonucu tanımsız davranışlardır. Sadece aynı şekilde davranın: Yapmayın. Ve iyi olacaksın. Ayrıca sihir kurallarını hatırlamanıza gerek kalmayacak. Ve sonra aslında oldukça yalındır.
back2dos,

8

Profesyonel bir matematikçi olarak Javscript'in aynılık operatöründe == (ayrıca "soyut karşılaştırma", "gevşek eşitlik" olarak da adlandırılır ) , varlıklar arasında dönüşlü , simetrik ve geçişli olmak üzere bir denklik ilişkisi kurma girişimi görüyorum . Ne yazık ki, bu üç temel özellikten ikisi başarısız:

==dönüşlü değil :

A == A yanlış olabilir, örneğin

NaN == NaN // false

==geçişli değil :

A == Bve B == Cbirlikte ima etme A == C, örn.

'1' == 1 // true
1 == '01' // true
'1' == '01' // false

Sadece simetrik özellik hayatta kalır:

A == BB == Ahangi ihlalin her durumda muhtemelen düşünülemez olduğunu ve ciddi isyanlara yol açacağını ima eder ;)

Eşdeğerlik ilişkileri neden önemlidir?

Çünkü bu, çok sayıda örnek ve uygulama tarafından desteklenen en önemli ve en yaygın ilişki türüdür. En önemli uygulama, varlıkların , ilişkilerin anlaşılmasının çok uygun ve sezgisel bir yolu olan denklik sınıflarına ayrıştırılmasıdır . Eşitlik olmamak ve eşdeğerlik sınıflarının olmamasına yol açar, bu da sezgisel olma ve iyi bilinen gereksiz karmaşıklıklara yol açar.

==Eşit olmayan bir ilişki için yazmak neden bu kadar korkunç bir fikir ?

Çünkü, benzerliği, eşitliği, uyumu, izomorfizmi, kimliği vb. İlginç bir ilişki olduğu için tanıdıklığımızı ve sezgimizi kırıyor.

Tür dönüşümü

Sezgisel bir denkliğe güvenmek yerine, JavaScript tür dönüştürmeyi sağlar:

Eşitlik operatörü, eğer aynı tipte değilse, operandları dönüştürür, sonra sıkı bir karşılaştırma yapar.

Ancak tür dönüşümü nasıl tanımlanır? Çok sayıda istisna dışında bir dizi karmaşık kural aracılığıyla mı?

Eşitlik ilişkisi kurmaya çalışıldı

Boolean. Açıkça trueve falseaynı değildir ve farklı sınıfta olmalıdır.

Sayılar. Neyse ki, sayıların eşitliği zaten iki farklı sayının asla aynı denklik sınıfında olmadığı iyi tanımlanmıştır. Matematikte budur. JavaScript içinde sayısının kavramıdır biraz deforme daha egzotik varlığı ile de -0, Infinityve -Infinity. Matematiksel sezgilerimiz , aynı sınıfta olmaları 0ve -0olması gerektiğini (gerçekte -0 === 0olduğu gibi true) belirtir, oysa ki sonsuzlukların her biri ayrı bir sınıftır.

Sayılar ve Booleanlar. Sayı sınıfları göz önüne alındığında, booleanları nereye koyacağız? falsebenzer olur 0ise, truebenzer olur 1, ancak başka bir numara:

true == 1 // true
true == 2 // false

Buraya truebirlikte koymak için herhangi bir mantık var 1mı? Kuşkusuz 1ayırt edilir, ama öyle -1. Şahsen dönüştürmek trueiçin bir neden görmüyorum 1.

Ve daha da kötüleşiyor:

true + 2 // 3
true - 1 // 0

Yani truegerçekten 1tüm sayılar arasında dönüştürülür ! Mantıklı mı? Sezgisel mi? Cevap egzersiz olarak bırakılmıştır;)

Peki ya bu:

1 && true // true
2 && true // true

Sadece boolean xile x && truevarlık trueolduğunu x = true. Bu da hem 1ve 2(ve diğer herhangi bir sayının 0) dönüştürdüğünü kanıtlar true! Varlık - Gösterdiği dönüşüm diğer önemli özelliği başarısız olmasıdır bijection . Yani iki farklı varlık aynı birine dönüştürebilir. Bu, başlı başına büyük bir sorun olmak zorunda değildir. Bu problemi, ne demek istiyorsak onu "aynılık" veya "gevşek eşitlik" ilişkisini tanımlamak için kullandığımız zaman büyük problem ortaya çıkar. Ancak bir şey açıktır - bir denklik ilişkisi olmayacak ve denklik sınıfları aracılığıyla sezgisel bir şekilde tanımlanmayacaktır.

Ama daha iyisini yapabilir miyiz?

En azından matematiksel olarak - kesinlikle evet! Boole'ler ve sayılar arasında basit bir denklik ilişkisi sadece falseve 0aynı sınıfta olmakla kurulabilir . Yani false == 0önemsiz olmayan tek eşitlik olacaktır.

Peki ya teller?

Sayılara dönüştürmek için başlangıçtaki ve sondaki boşluklardan dizeleri kırpabiliriz, ayrıca öndeki sıfırları da görmezden gelebiliriz:

'   000 ' == 0 // true
'   0010 ' == 10 // true

Böylece bir string için basit bir kural elde ediyoruz - boşlukları ve öndeki sıfırları kırpın. Bir sayı veya boş bir dize alırız, bu durumda bu sayıya veya sıfıra dönüştürürüz. Ya da bir sayı alamıyoruz, bu durumda dönüştürmüyoruz ve yeni bir ilişki kurmuyoruz.

Bu şekilde, toplam boole, sayı ve karakter dizisi üzerinde mükemmel bir denklik ilişkisi elde edebiliriz! Bunun dışında ... JavaScript tasarımcılarının açıkça başka bir fikri var:

' ' == '' // false

Böylece, her ikisine de dönüşen iki tel 0aniden birbirine benzemez! Neden ya da neden? Kurala göre, tamamen eşit olduklarında dizgiler kesin olarak eşit olur! Yalnızca bu kural gördüğümüz gibi geçişliliği bozmaz, aynı zamanda gereksizdir! ==Onu diğeriyle tamamen aynı yapmak için başka bir operatör yaratmanın amacı nedir ===?

Sonuç

Gevşek eşitlik operatörü ==, bazı temel matematik yasalarına uyması halinde çok faydalı olabilirdi. Ancak ne yazık ki olmadığı gibi, faydası da zarar görüyor.


Ne hakkında NaN? Ayrıca, dizelerle karşılaştırma için belirli bir sayı formatı uygulanmadıkça, sezgisel olmayan dize karşılaştırması ya da geçiş yapmama sonucu ortaya çıkmalıdır.
Solomon Ucko

@SolomonUcko NaNkötü vatandaş olarak davranıyor :-). Geçiş, sezgisel olsun veya olmasın, herhangi bir denklik karşılaştırması için desteklenebilir ve sağlanmalıdır.
Dmitri Zaitsev

7

Evet, bunun için bir kullanım durumu ile karşılaştım, yani bir sayısal değeri olan bir anahtar karşılaştırırken :

for (var key in obj) {
    var some_number = foo(key, obj[key]);  // or whatever -- this is just an example
    if (key == some_number) {
        blah();
    }
}

Ben o kadar karşılaştırma yapmak için çok daha fazla doğal olduğunu düşünüyorum key == some_numberolarak değil Number(key) === some_numberya da key === String(some_number).


3

Bugün oldukça faydalı bir uygulama ile karşılaştım. 01Normal sayıları gibi yastıklı sayıları karşılaştırmak istiyorsanız , iyi ==çalışıyor. Örneğin:

'01' == 1 // true
'02' == 1 // false

0 değerini kaldırmak ve bir tam sayıya dönüştürmek için sizi kurtarır.


4
Bunu yapmanın 'doğru' yolunun '04'-0 === 4, ya da muhtemelenparseInt('04', 10) === 4
ratbum

Bunu yapabileceğinin farkında değildim.
Jon Snow,

7
Bunu çok anladım.
Jon Snow,

1
@ratbum or+'01' === 1
Eric Lagergren

1
'011' == 011 // falsekatı olmayan modda ve sıkı modda SyntaxError. :)
Brian S

3

Bunun gecikmiş bir cevap olduğunu biliyorum, fakat bunun hakkında kötü bir karışıklık var gibi görünüyor nullve undefinedhangi IMHO'nun ==kötülük yaptığı, daha çok geçişlilik eksikliği, ki yeterince kötü. Düşünmek:

p1.supervisor = 'Alice';
p2.supervisor = 'None';
p3.supervisor = null;
p4.supervisor = undefined;

Bunlar ne anlama geliyor?

  • p1 Adı "Alice" olan bir süpervizöre sahip.
  • p2 Adı "Yok" olan bir amir var.
  • p3açıkça, açıkça, bir süpervizör yok .
  • p4süpervizör olabilir veya alabilir. Bilmiyoruz, umursamıyoruz, bilmememiz gerekmiyor (gizlilik sorunu?), Bizim işimiz değil.

Kullandığınız zaman ==konflasyona başlıyorsunuz nullve undefinedbu tamamen uygunsuz. İki terim tamamen farklı şeyler ifade ediyor! Bir süpervizörüm olmadığını söylemek, çünkü süpervizörümün kim olduğunu söylemeyi reddettiğim için.

Anladığım kadarıyla bu farklılığı önemsemeyen nullve undefinedbu terimleri farklı şekilde kullanmayı seçmeyen programcılar var . Dünyanız kullanmıyor nullve undefineddoğru kullanmıyorsa veya bu terimlerle ilgili kendi yorumlarınızı vermek istiyorsanız, öyle olsun. Bunun iyi bir fikir olduğunu sanmıyorum.

Şimdi bu arada ben sorunum yok nullve undefinedher iki varlık falsy! Söylemesi mükemmel tamam

if (p.supervisor) { ... }

ve daha sonra nullve undefineddenetleyiciyi işleyen kodun atlanmasına neden olur. Bu doğru, çünkü bir süpervizör tanımıyoruz veya bilmiyoruz. Hepsi iyi. Ancak bu iki durum eşit değil . Bu yüzden ==yanlış. Yine, şeyler sahte olabilir ve dinamik diller için harika bir ördek yazma anlamında kullanılabilir. JavaScript, Pythonic, Rubyish, vb. Uygun. Fakat yine de, bu şeyler eşit değil.

: Ya ben olmayan geçişlilik başladı alamadım "0x16" == 10, 10 == "10"ama "10" == "0x16". Evet, JavaScript zayıf türleridir. Evet, zorlayıcı. Ancak zorlayıcılık hiçbir zaman eşitlik için geçerli olmamalıdır.

Bu arada, Crockford'un güçlü görüşleri var. Ama ne biliyorsun? Burada haklı!

FWIW Anladığım kadarıyla durumların olduğunu ve kişisel olarak karşılaştığımı biliyorum ==! Rakamlar için dize girişi almak ve diyelim ki, 0 ile karşılaştırmak gibi. Ancak, bu hack. Dünyanın yanlış bir modeli için bir takas olarak rahatınız.

TL; DR: yanlışlık harika bir kavram. Eşitliğe uzanmamalı.


Farklı durumları gösterdiğiniz için teşekkür ederim :) Ancak, p5typeof(p5.supervisor) === typeof(undefined)
eksiksiniz
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.