JavaScript'in Gizli Özellikleri? [kapalı]


312

Her programcının bilmesi gereken JavaScript'in hangi "Gizli Özellikleri" olduğunu düşünüyorsunuz?

Aşağıdaki soruların cevaplarının mükemmel kalitesini gördükten sonra JavaScript sormanın zamanı geldiğini düşündüm.

JavaScript şu anda tartışmasız en önemli İstemci Tarafı dili olmasına rağmen (sadece Google'a sorun), çoğu web geliştiricisinin gerçekten ne kadar güçlü olduğunu takdir etmesinin şaşırtıcı olması.


1
Şunu mu demek istediniz: "Bu diğer soruyu temsil eden noktaları ve görüşleri gördükten sonra, kendimi geliştirmek için neredeyse aynı soruyu soracağımı düşündüm"? ;-)
Bobby Jack

1
Tabii, kötümser. :) Bunu bir topluluk sorusu haline getirmeyi düşünmüştüm. Ayrıca, belirli sayıda puan aldıktan sonra, hepsi azalan geri dönüşler.
Allain Lalonde

1
Yeterince adil - temsilcisi 'ihtiyacınız' gibi görünmüyor! Sanırım sadece C # bir ile büyük bir sorun var - bana tam olarak bu sitenin amaçlandığı soru türü gibi görünmüyor.
Bobby Jack

3
Evet, belki hayır, ama cevaplardaki bilgiyi harika buldum. Ortalama bir # C # programcı SO için değilse tek bir yerde ortaya çıkarmak zor olurdu düşünüyorum. Aynı zor kazanılan listeyi bulmak için onunla oynamak yıllar alacaktı.
Allain Lalonde

7
10 yıldır profesyonel olarak JavaScript yazıyorum ve bu konudan bir veya üç şey öğrendim. Teşekkürler Alan!
Andrew Hedges

Yanıtlar:


373

Bir işlev için herhangi bir parametre tanımlamanız gerekmez. Sadece işlevin argumentsdizi benzeri nesnesini kullanabilirsiniz.

function sum() {
    var retval = 0;
    for (var i = 0, len = arguments.length; i < len; ++i) {
        retval += arguments[i];
    }
    return retval;
}

sum(1, 2, 3) // returns 6

117
Her ne kadar argümanlar bir dizi gibi davransa da, gerçek bir javascript Array değil - sadece bir nesne. Böylece join (), pop (), push (), slice () ve benzerlerini yapamazsınız. (İsterseniz gerçek bir diziye dönüştürebilirsiniz: "var argArray = Array.prototype.slice.call (arguments);")
Jacob Mattison

51
Ayrıca, Arguments nesnesine erişmenin nispeten pahalı olduğunu da belirtmek gerekir - en iyi örnekler Safari, Firefox ve Chrome gecelerinde, yalnızca argumentsnesneye başvurmanın bir işlevi çağırmayı çok daha yavaş hale getirdiğidir - ör. if (false) argümanları; mükemmel acıtacak.
olliej

48
Aynı şekilde, argümanların geçerli fonksiyonun kendisi olan bir "callee" özelliği vardır. Bu anonim fonksiyonları ile özyineleme yapmak için izin verir, serin!
Vincent Robert

4
@Nathan "f (x, y, z)", "f ([x, y, z])" den daha iyi görünür.
Mark Cidade

16
@Vincent Robert: Lütfen arguments.calleekullanımdan kaldırıldığını unutmayın .
ken

204

Douglas Crockford'un mükemmel kitabı JavaScript: The Good Parts'ın çoğunu alıntılayabilirim .

Ama senin için sadece bir tane alacağım, her zaman kullan ===ve!== yerine ==ve!=

alert('' == '0'); //false
alert(0 == ''); // true
alert(0 =='0'); // true

==geçişli değildir. Eğer kullanırsanız ===beklendiği gibi bu tabloların tümü için yanlış verecekti.


29
Birçok insanın Crockford'un her şeyi bildiğini düşünmesi utanç verici. Verilmiş, adam eleştirilerinin çoğuyla işaretin üstünde, ama eşyalarını pek çok devs gibi battaniye desteği vermekten alıkoyuyorum ...
Jason Bunting

21
Jason'ın uyarısını ikinci olarak verdim. Kendi içinde kitap çok ilginç olduğunu ve iyi bir tavsiye bir sürü verir, ama DC edilir uzak çok şeyler yapmanın onun yolu yalnızca doğru yol olduğunu ikna, her şey "kusurlu" dir. Bazı örnekler isterseniz, JSLint Yahoo Group'ta verdiği yanıtlara bakın.
Zilk

30
Dinamik yazarak kafanız karıştıysa ve "gerçekten" eşit olmasını istiyorsanız == yerine === kullanın. Dinamik yazmayı anlayanlarımız, 0 == '' veya 0 == '0' gibi, yayınlamak istediğimizi bildiğimiz durumlar için == kullanmaya devam edebilir.
thomasrutter

20
== ve === dinamik yazmayla ilgili değil. == farklı bir canavar olan baskı türünü yapar. Eğer string / number / etc'ye yayın yapmak istediğinizi biliyorsanız, bunu açıkça yapmalısınız.
Rene Saarsoo

15
Ben en korkunç parçası mı ==olduğu '\n\t\r ' == 0=> trueD: ...
Shrikant Sharat

189

Fonksiyonlar JavaScript'te birinci sınıf vatandaşlardır:

var passFunAndApply = function (fn,x,y,z) { return fn(x,y,z); };

var sum = function(x,y,z) {
  return x+y+z;
};

alert( passFunAndApply(sum,3,4,5) ); // 12

Fonksiyonel programlama teknikleri zarif javascript yazmak için kullanılabilir .

Özellikle fonksiyonlar parametre olarak iletilebilir, örneğin Array.filter () bir geri çağrıyı kabul eder:

[1, 2, -1].filter(function(element, index, array) { return element > 0 });
// -> [1,2]

Yalnızca belirli bir işlev kapsamında bulunan bir "özel" işlevi de bildirebilirsiniz:

function PrintName() {
    var privateFunction = function() { return "Steve"; };
    return privateFunction();
}

3
Javascript'te işlev yapmanın üç yolu vardır: işlev toplamı (x, y, z) {return (x + y + z); } ve var sum = new Function ("x", "y", "z", "return (x + y + z);"); diğer yollardır.
Marius

6
Veri olarak işlev kavramı kitabımda kesinlikle büyük puanlar kazanıyor.
Jason Bunting

Sadece belirli bir işlev kapsamında bulunan bir "özel" işlevinin nasıl kullanılacağını göstermek için örneği güncelledim.
Chris Pietschmann

new Function()kadar kötüdür eval. Kullanmayın.
Nicolás

11
bunun gizli bir özellik olduğundan emin değilim ... daha çok temel bir özellik gibi.
Claudiu

162

Bir nesnede bir anahtar olup olmadığını kontrol etmek için in operatörünü kullanabilirsiniz :

var x = 1;
var y = 3;
var list = {0:0, 1:0, 2:0};
x in list; //true
y in list; //false
1 in list; //true
y in {3:0, 4:0, 5:0}; //true

Nesne değişmezlerini çok çirkin bulursanız, parametresiz işlev ipucu ile birleştirebilirsiniz:

function list()
 { var x = {};
   for(var i=0; i < arguments.length; ++i) x[arguments[i]] = 0;
   return x
 }

 5 in list(1,2,3,4,5) //true

22
Çok akıllıca değil, bir anahtarın mevcut olup olmadığını kontrol eder, bir değer olup olmadığını kontrol eder. listede x; sadece x [1]! = null olduğu için çalışır, 1 değeri orada olduğu için değil.
Armin Ronacher

1
Tekniği ina'da kullanmadım, bu yüzden daha önce nesne değişmezlerini kullandığımı unuttum. Düzeltme için teşekkürler.
Mark Cidade

34
Ayrıca, dikkatli olun: in operatörü de prototip zincirini test eder! Birisi Object.prototype üzerinde '5' adlı bir özellik koyduysa, ikinci örnek '(1, 2, 3, 4) listesinde' 5'i çağırsanız bile true değerini döndürür ... hasOwnProperty'yi kullansanız iyi olur yöntem: list (1, 2, 3, 4) .hasOwnProperty (5), Object.prototype '5' özelliğine sahip olsa bile false değerini döndürür.
Martijn

3
En genel çözüm için, bir nesnenin kendi özelliğine sahip olup olmadığını test edebilen bir çözüm, "hasOwnProperty" olarak adlandırılmış olsa bile, sonuna kadar gitmeniz gerekir: Object.prototype.hasOwnProperty.call (nesne, ad) ;
Kris Kowal

1
@Kris, birisi Object.prototype.hasOwnProperty;) üzerine yazmazsa
Nick

153

Değişkenlere varsayılan değerler atama

||Varsayılan bir değer sağlamak için bir atama ifadesinde mantıksal veya işleci kullanabilirsiniz :

var a = b || c;

aDeğişken değerini alacak ceğer sadece bbir falsy (eğer null, false, undefined, 0, empty string, veya NaN), aksi adeğerini alacakb .

Bu, sağlanmadığında bir bağımsız değişkene varsayılan bir değer vermek istediğinizde genellikle işlevlerde yararlıdır:

function example(arg1) {
  arg1 || (arg1 = 'default value');
}

Olay işleyicilerinde IE yedek örneği:

function onClick(e) {
    e || (e = window.event);
}

Aşağıdaki dil özellikleri uzun zamandır bizimle birlikte, tüm JavaScript uygulamaları bunları destekliyor, ancak ECMAScript 5. Baskıya kadar spesifikasyonun bir parçası değildi :

debuggeraçıklama

Açıklama: § 12.15 Hata ayıklayıcı bildirimi

Bu ifade, kesme noktalarını kodunuza programlı olarak aşağıdaki yollarla koymanızı sağlar :

// ...
debugger;
// ...

Bir hata ayıklayıcı varsa veya etkinse, hemen o satırda, kırılmasına neden olur.

Aksi takdirde, hata ayıklayıcı yoksa veya etkin değilse, bu ifadenin gözlemlenebilir bir etkisi yoktur.

Çok Satırlı Dize değişmez değerleri

Açıklama: § 7.8.4 Dize Değişmezleri

var str = "This is a \
really, really \
long line!";

Dikkatli olmalısınız, çünkü yanındaki karakterin bir satır sonlandırıcı \ olması gerekir , \örneğin sonrasında boşluk varsa , kod tam olarak aynı görünür , ancak a işareti yükselir SyntaxError.


28
Boş değilse, yanlış kabul edilirse değil. a = 0 || 42; 42 verecek. Bu Python's ile karşılaştırılabilir veya C # değil ?? Şebeke. C # davranışını istiyorsanız, a = (b === null)? c: b;
Armin Ronacher

ASP.NET üzerinde geliştirirseniz Visual Studio'da da çalışır :)
chakrit 23:10

2
Keşke uygun olsaydı || sadece tanımsız için. Ben aşırı yük yöntemi öykünmesi oluşturmak istedim, çünkü son argüman isteğe bağlı ve bunun yerine bir varsayılan değer kullanılacak bugün 0 için ısırıldı.
egaga

Bu numara + 1, varsayılan Google Analytics snippet'i tarafından kullanılır. `var _gaq = _gaq || []; '; aşırı hevesli kullanıcıların kendi çalışmalarının üzerine yazmasını önler.
Yahel

2
Çok satırlı dizgi değişmez tekniğini bilmiyordum. Harika, teşekkürler.
Charlie Flowers

145

JavaScript'in blok kapsamı yoktur (ancak kapanması vardır, bu yüzden onu diyelim mi?).

var x = 1;
{
   var x = 2;
}
alert(x); // outputs 2

3
Bu iyi bir tanesidir. Çoğu C benzeri dilden gerçekten önemli bir farktır.
Martin Clarke

9
Her zaman "var tmp = function () {/ * blok kapsamı * /} ();" yapabilirsiniz. Sözdizimi çirkin, ama işe yarıyor.
Joeri Sebrechts

3
Veya yalnızca Firefox ise "let" kullanabilirsiniz: stackoverflow.com/questions/61088/…
Eugene Yokota

10
ya da sadece: (function () {var x = 2;}) (); uyarı (x türü); // undefined
Pim Jager

@Pim: JSLint diyor ki: "Çağrıyı işlevi içeren ebeveynlere taşı." "İşlev" ile "(" arasında tam bir boşluk olması bekleniyor.)
Merhaba71

144

Nesne özelliklerine []yerine.

Bu, bir değişkenle eşleşen bir özelliği aramanızı sağlar.

obj = {a:"test"};
var propname = "a";
var b = obj[propname];  // "test"

Bunu, adı yasal bir tanımlayıcı olmayan nesne özelliklerini almak / ayarlamak için de kullanabilirsiniz.

obj["class"] = "test";  // class is a reserved word; obj.class would be illegal.
obj["two words"] = "test2"; // using dot operator not possible with the space.

Bazı insanlar bunu bilmiyor ve bunun gibi eval () kullanıyorlar , bu gerçekten kötü bir fikir :

var propname = "a";
var a = eval("obj." + propname);

Bu, okunması daha zordur, hataları bulmak daha zordur (jslint kullanamazsınız), yürütülmesi daha yavaştır ve XSS istismarlarına yol açabilir.


eval nadiren gerekli olsa da kötüdür
Doug Domeny

Bunu keşfettiğimde asla eval kullanmam ve hatırlamam. Beni çok mutlu etti.

Özetle, nesne özelliklerine hem nokta hem de alt simge gösterimi yoluyla erişilebilir
Russ Cam

9
Nokta referanslamanın aslında parantez için sözdizimi şekeri olduğunu belirtmek ilginçtir. foo.bar, yine de özelliğe göre, aynı şekilde davranır foo["bar"]. ayrıca her şeyin bir string özelliği olduğunu unutmayın. dizi erişimi yaptığınızda bile array[4], 4 bir dizeye dönüştürülür (yine en azından ECMAScript v3 spec'e göre)
Claudiu

Sanırım her JS programcısı bunu bilmeli.
Cem Kalyoncu

144

Belirli bir konuda iyi bir JavaScript referansı için Google'da çalışıyorsanız, sorgunuza "mdc" anahtar kelimesini ekleyin; ilk sonuçlarınız Mozilla Geliştirici Merkezi'nden olacaktır. Yanımda çevrimdışı referans veya kitap taşımıyorum. Ben her zaman doğrudan aradığım şey almak için "mdc" anahtar kelime hile kullanın. Örneğin:

Google: javascript dizi sıralaması mdc
(çoğu durumda "javascript" i atlayabilirsiniz)

Güncelleme: Mozilla Developer Center , Mozilla Developer Network olarak yeniden adlandırıldı . "Mdc" anahtar kelime hilesi hala işe yarıyor, ancak kısa süre içinde bunun yerine "mdn" kullanmaya başlamamız gerekebilir .


50
Vay, harika bir kaynak. Anında crappy w3schools daha iyi ...
DisgruntledGoat

11
Firefox'taysanız Google'a bile gerek yoktur: adres çubuğuna "dizi mdc" yazın ve Enter tuşuna basın.
Sasha Chedygov

2
en iyi yanı, bu yığın taşması sorusunun sonuçların ilk sayfasında nasıl
olduğudur

5
Bir destek: promjs.com , MDC sonuçlarını Google arama sonuçlarında daha da ileri götürmek için bir SEO girişimi.
Yahel

3
Şimdi MDN doktor merkezi, bu yüzden 'mdc' anahtar kelimesi hala geçerli :)
Aleadam

143

Belki bazıları için biraz açık ...

Firebug'u yükleyin ve console.log ("merhaba") kullanın. Rasgele uyarı () kullanmaktan çok daha iyi; birkaç yıl önce çok şey yaptığımı hatırlıyorum.


12
Kodunuzu Firebug yüklü olmayan diğer kullanıcılara göndermeden önce konsol deyimlerini kaldırmayı unutmayın.
Chris Noe

161
işlev günlüğü (msg) {if (console) console.log (msg) başka uyarı (msg)}
Josh

4
Daha da iyisi, günlük ifadelerinden önce ';;;' ve küçültmek sizin için halleder. (En azından, kullandığım Perl modülü bu özelliğe sahip ve sıradan olduğunu iddia ediyor.)
Kev

10
Josh: Konsol tanımlanmadığı için işe yaramayacak. Typeof console! == "undefined" veya window.console öğesini kontrol edebilirsiniz.
Eli Gray

23
Her zaman şunları ekleyin: if (typeof ('console') == 'tanımsız') {console = {log: function () {}}; } sonra console.log'u kullanmaya devam edebilirsiniz ve hiçbir şey yapmaz.
gregmac

120

Özel Yöntemler

Bir nesnenin özel yöntemleri olabilir.

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;

    // A private method only visible from within this constructor
    function calcFullName() {
       return firstName + " " + lastName;    
    }

    // A public method available to everyone
    this.sayHello = function () {
        alert(calcFullName());
    }
}

//Usage:
var person1 = new Person("Bob", "Loblaw");
person1.sayHello();

// This fails since the method is not visible from this scope
alert(person1.calcFullName());

16
Bu gerçekten özel bir işlev değil - daha çok yerel bir kapsamdaki bir işlev değişkeni.
Keith

6
Doğru ama tüm operasyonel tanımlarla bunun bir yöntem olduğunu düşünebilirim. Örnek durumuna erişimi olan ve yalnızca bu örnek tarafından görülebilen bir ada sahip bir kod bloğudur. Özel yöntem tanımınız nedir?
Allain Lalonde

14
@Zach, kesinlikle! Sınıf tabanlı OO dilleriyle yıllarca çalıştıktan sonra, OO kavramlarının yalnızca bir uygulaması olduğunu unutmak kolaydır. Tabii ki,
JS'ye

5
Sadece merak ediyorum, person1'in bir Hukuk Blogu var mı? ;-)
travis

4
Tutuklanan gelişim referansı için +1
Domenic

99

Ayrıca Crockford'un "Javascript: İyi Parçalar" bölümünde de bahsedilmiştir:

parseInt()tehlikeli. Bir dizeyi uygun tabandan haberdar etmeden iletirseniz, beklenmeyen sayılar döndürebilir. ÖrneğinparseInt('010') , 10 değil, 8 döndürür. Bir tabanı parseInt öğesine geçirmek doğru çalışmasını sağlar:

parseInt('010') // returns 8! (in FF3)
parseInt('010', 10); // returns 10 because we've informed it which base to work with.

13
Kod incelemelerini yaparken her zaman bunu arayın. "10" u bırakmak çoğu testte fark edilmeyen yaygın bir hatadır.
Doug Domeny

Yıllar önce sayı tabanı sorunu tarafından yandım ve bu kadar sezgisel bir şeyi hiç unutmadım. Bir süredir merak edeceğiniz için işaret etmek harika bir şey.
JamesEggers

4
Neden kullanmıyorsunuz Math.floorveya Number? 10 === Math.floor("010"); 10 === Number("010");yüzen:42 === Math.floor("42.69"); 42.69 === Number("42.69");
birileri

1
@Infinity Henüz gönderilmiş bir cevap yoksa, yapmalısınız. Yerleşik işlev davranışını geçersiz kılmanın bu kadar basit olduğu hakkında hiçbir fikrim yoktu. Tabii ki, diğer sitelerden ödünç aldıkları kod paketlerine biraz daha yakından bakmalıdır. Bu zararsız parseIntfonksiyon, çok zararsız olmayan bir şeyi yapmak için kolayca yapılabilir.
bob-the-destroyer

6
@Infinity: fn 'kodlama hatasını' vurgulamak için yeniden tanımlamaya ne dersiniz? __parseInt = parseInt; parseInt = function (str, base) { if (!base) throw new Error(69, "All your base belong to us"); return __parseInt(str, base); }
JBRWilkinson

97

İşlevler nesnedir ve bu nedenle özelliklere sahip olabilirler.

fn = işlev (x) {
   // ...
}

fn.foo = 1;

fn.next = işlev (y) {
  //
}

13
Bu çok faydalı bir ipucu. Örneğin, varsayılan değerleri işlevin bir özelliği olarak ayarlayabilirsiniz. Örneğin: myfunc.delay = 100; Ardından kullanıcılar varsayılan değeri değiştirebilir ve tüm işlev çağrıları yeni varsayılan değeri kullanır. Örneğin: myfunc.delay = 200; işlevim ();
BarelyFitz

Yararlı ... ve tehlikeli!
palswim

Özensiz görünüyor, Bunu neden bir değişken yerine kullanıyorsunuz?
instantsetsuna

1
@instantsetsuna: Neden başka sahip ayrı bir değişken? Her zamanki gibi bu "uygun / yararlı olduğunda kullan" ;-)
VolkerK

91

Kendi kendini icra eden işlevler söylemek zorundayım.

(function() { alert("hi there");})();

Javascript'in blok kapsamı olmadığından, yerel değişkenleri tanımlamak istiyorsanız kendi kendini yürütme işlevini kullanabilirsiniz:

(function() {
  var myvar = 2;
  alert(myvar);
})();

Burada, myvarküresel kapsamı etkilemez veya kirletmez ve işlev sona erdiğinde kaybolur.


2
Bu ne işe yarar? Aynı sonucu uyarıyı işlevin dışına koymaktan da alırsınız.
PotatoEngineer

7
Bu, uyarı ile ilgili değil, aynı anda bir işlevi tanımlamak ve yürütmekle ilgilidir. Kendi kendini yürütme işlevinin bir değer döndürmesini ve işlevi bir parametre olarak başka bir işleve geçirmesini sağlayabilirsiniz.
ScottKoon

5
@ Kapsül kapsülleme için iyidir.
Mike Robinson

22
Blok kepçesi için de iyidir.
Jim Hunziker

24
Evet, tüm .jsdosyalarımı anonim kendi kendine yürütme işlevine ekliyorum ve içinde global olarak erişilebilir olmasını istediğim her şeyi windownesneye ekliyorum . Küresel ad alanı kirliliğini önler.
cdmckay

83

Bir işlev tarafından kaç parametre beklendiğini bilin

function add_nums(num1, num2, num3 ){
    return num1 + num2 + num3;
}
add_nums.length // 3 is the number of parameters expected.

İşlev tarafından kaç parametre alındığını bilin

function add_many_nums(){
    return arguments.length;
}    
add_many_nums(2,1,122,12,21,89); //returns 6

23
İlk kısmı hiç bilmiyordum. Güzel!
mcjabberz

1
Benzer şekilde, bir işlevin kaç argümanla beklediğini öğrenebilirsiniz function.length.
Xavi

6
@ Cevabın 1. kısmı olan
Xavi

79

İşte bazı ilginç şeyler:

  • Karşılaştırma NaN(hatta herhangi bir şeyle NaN) içerdiğini, her zaman yanlıştır ==, <ve >.
  • NaN Sayı Değil anlamına gelir, ancak türü sorarsanız aslında bir sayı döndürür.
  • Array.sort karşılaştırıcı işlevi alabilir ve hızlı sıralamaya benzer bir sürücü tarafından çağrılır (uygulamaya bağlıdır).
  • Düzenli ifade "sabitler", eşleştirdikleri son şey gibi durumu koruyabilir.
  • JavaScript bazı sürümleri erişmenize izin $0, $1,$2 bir regex üzerinde üye.
  • nullbaşka hiçbir şeye benzemez. Ne bir nesne, ne bir boole, bir sayı, bir dize, ne de undefined. Biraz "alternatif" gibi undefined. (Not: typeof null == "object")
  • En dıştaki bağlamda, this aksi takdirde adlandırılamayan [Global] nesneyi verir.
  • İle değişken bildirme var otomatik olarak bildirilmesine güvenmek yerine, bildirilmesi, çalışma zamanına bu değişkene erişimi optimize etme konusunda gerçek bir şans verir
  • withYapı böyle optimzations yok edecek
  • Değişken adları Unicode karakterler içerebilir.
  • JavaScript normal ifadeleri aslında normal değildir. Perl'in normal ifadelerine dayanırlar ve değerlendirilmeleri çok uzun zaman alan gözcülerle ifadeler oluşturmak mümkündür.
  • Bloklar hedef olarak etiketlenebilir ve kullanılabilir break. Döngüler etiketlenebilir ve hedefi olarak kullanılabilir continue.
  • Diziler seyrek değildir. Aksi halde boş bir dizinin 1000'inci öğesini ayarlamak, onu doldurmalıdır undefined. (uygulamaya bağlıdır)
  • if (new Boolean(false)) {...}{...}bloğu yürütecek
  • Javascript'in normal ifade motorları uygulamaya özeldir: örn. "Taşınabilir olmayan" düzenli ifadeler yazmak mümkündür.

[iyi yorumlara yanıt olarak biraz güncellendi; lütfen yorumlara bakın]


5
null aslında (özel) bir nesnedir. typeof null"nesne" döndürür.
Ateş Goral

4
[Global] nesnesini şu şekilde de elde edebilirsiniz: var glb = function () {return this; } ();
Zilk

2
Bir tarayıcıdaki javascript'teki global nesne pencere nesnesidir. Global kapsamdayken: window.a == a;
Pim Jager

8
"Diziler seyrek değildir" uygulamaya bağlıdır. Bir [1000] değerini ayarlayıp [999] 'a bakarsanız, evet, budur undefined, ancak varolmayan bir dizin ararken aldığınız varsayılan değer budur. Bir [2000] 'i kontrol ettiyseniz, bu da olurdu undefined, ancak bu henüz için bellek ayırdığınız anlamına gelmez. IE8'de, JScript motorunun o anda nasıl hissettiğine bağlı olarak bazı diziler yoğundur ve bazıları seyrektir. Daha fazla bilgiyi
Chris Nielsen

2
@Ates ve @SF: typeof, farklı türler için "nesne" döndürür. Ancak, nasıl çalıştığını ve hangi türlerin "nesne" olarak tanımlandığını öğrendikten sonra, uygulamasında en azından güvenilir ve tutarlıdır.
thomasrutter

77

Partiye geç kaldığımı biliyorum, ama +operatörün kullanışlılığının "bir şeyi bir sayıya dönüştür" ün ötesine geçmediğine inanamıyorum . Belki de bir özellik ne kadar iyi gizlenmiştir?

// Quick hex to dec conversion:
+"0xFF";              // -> 255

// Get a timestamp for now, the equivalent of `new Date().getTime()`:
+new Date();

// Safer parsing than parseFloat()/parseInt()
parseInt("1,000");    // -> 1, not 1000
+"1,000";             // -> NaN, much better for testing user input
parseInt("010");      // -> 8, because of the octal literal prefix
+"010";               // -> 10, `Number()` doesn't parse octal literals 

// A use case for this would be rare, but still useful in cases
// for shortening something like if (someVar === null) someVar = 0;
+null;                // -> 0;

// Boolean to integer
+true;                // -> 1;
+false;               // -> 0;

// Other useful tidbits:
+"1e10";              // -> 10000000000
+"1e-4";              // -> 0.0001
+"-12";               // -> -12

Tabii ki, tüm bunları Number()bunun yerine kullanarak yapabilirsiniz , ancak +operatör çok daha güzel!

Prototip valueOf()yöntemini geçersiz kılarak bir nesne için sayısal bir dönüş değeri de tanımlayabilirsiniz . Bu nesne üzerinde yapılan herhangi bir sayı dönüşümü NaN, valueOf()yöntemin dönüş değeriyle sonuçlanmaz :

var rnd = {
    "valueOf": function () { return Math.floor(Math.random()*1000); }
};
+rnd;               // -> 442;
+rnd;               // -> 727;
+rnd;               // -> 718;

Basitçe yapabilirsiniz 0xFF, vb +"0xFF".
nyuszika7h

9
Nyuszika7H @: Eğer nokta eksik diğer temelögeye ve nesneleri coercing edilmiş olan biriyseniz için numaralar. Tabii ki yazabilirsiniz 0xFF, 1bunun yerine yazabileceğiniz gibi +true. İsterseniz +("0x"+somevar)alternatif olarak kullanabileceğinizi öneriyorum parseInt(somevar, 16).
Andy E

75

" JavaScript Uzatma yöntemleri prototip özelliği aracılığıyla".

Array.prototype.contains = function(value) {  
    for (var i = 0; i < this.length; i++) {  
        if (this[i] == value) return true;  
    }  
    return false;  
}

Bu, containstüm Arraynesnelere bir yöntem ekleyecektir . Bu sözdizimini kullanarak bu yöntemi çağırabilirsiniz

var stringArray = ["foo", "bar", "foobar"];
stringArray.contains("foobar");

18
Bu genellikle kötü bir fikir olarak kabul edilir, çünkü diğer kodlar (sizin değil) Array nesnesi hakkında varsayımlar yapabilir.
Chris Noe

39
Array nesnesi hakkında varsayımlar yapmak genellikle kötü bir fikir olarak kabul edilir. :(
göz kapaksızlığı

Ahmmmm .. javascript 1.6 dizi ekstralar? indeksi? zil çalıyor mu?
Breton

2
@Breton: Array sınıfına özgü bir şey değil, sadece bir örnek. Bunu yeni Date (). ToString (); maske dizesinin kullanılmasına izin verir. Herhangi bir nesne genişletilebilir ve tüm örnekleri yeni yöntemi alır.
Esteban Küber

1
@Mathias: Bu DOM ile ilgili değil.
dolmen

60

Bir özelliği bir nesneden düzgün bir şekilde kaldırmak için, özelliği yalnızca tanımsız olarak ayarlamak yerine silmeniz gerekir :

var obj = { prop1: 42, prop2: 43 };

obj.prop2 = undefined;

for (var key in obj) {
    ...

Prop2 özelliği yine de yinelemenin bir parçası olacaktır. Prop2'den tamamen kurtulmak istiyorsanız , şunları yapmalısınız:

delete obj.prop2;

Özellikler arasında yineleme yaptığınızda prop2 özelliği artık görünmez .


3
Delete deyiminin tarayıcıya özgü tuhaflıkları olmadan olmadığını unutmayın. Örneğin, IE'de denerseniz ve nesne yerel JS nesnesi değilse (kendiniz eklediğiniz bir özelliği silerken bile) bu büyük bir hatayla başarısız olur. Ayrıca, myvar'ı silmek gibi bir değişkeni silmek için tasarlanmamıştır; ancak bunun bazı tarayıcılarda işe yaradığını düşünüyorum. Yukarıdaki cevap kodu oldukça güvenli görünüyor.
thomasrutter

bu arada, undefined de bir değişken olabilir! Var undefined = "bir şey" deneyin
Johann Philipp Strathausen

57

with.

Nadiren kullanılır ve açıkçası, nadiren faydalıdır ... Ancak, sınırlı durumlarda, kullanımları vardır.

Örneğin: nesne değişmez değerleri, yeni bir nesnenin özelliklerini hızlı bir şekilde ayarlamak için oldukça kullanışlıdır . Ancak , varolan bir nesnenin özelliklerinin yarısını değiştirmeniz gerekirse ne olur ?

var user = 
{
   fname: 'Rocket', 
   mname: 'Aloysus',
   lname: 'Squirrel', 
   city: 'Fresno', 
   state: 'California'
};

// ...

with (user)
{
   mname = 'J';
   city = 'Frostbite Falls';
   state = 'Minnesota';
}

Alan Storm bu biraz tehlikeli olabilir işaret: içerik olarak kullanılan nesne yoksa sahip muhtemelen oluşturma veya genel değişken üzerine, özelliklerinden biri, dış kapsam giderilmiş tahsis edilir. Varsayılan veya boş değerlere sahip özelliklerin tanımsız bırakıldığı nesnelerle çalışmak için kod yazmaya alışkınsanız bu özellikle tehlikelidir:

var user = 
{
   fname: "John",
// mname definition skipped - no middle name
   lname: "Doe"
};

with (user)
{
   mname = "Q"; // creates / modifies global variable "mname"
}

Bu nedenle, bu withtür bir atama için ifadenin kullanılmasından kaçınmak muhtemelen iyi bir fikirdir .

Ayrıca bkz: JavaScript'in “with” ifadesinin yasal kullanımları var mı?


29
Geleneksel bilgelikten kaçınılmalıdır. Kullanıcı nesnesi bahsettiğiniz özelliklerden birine sahip değilse, bloğun sözde kapsamının dışındaki değişken değiştirilir. Bu şekilde böcekler yatar. More info at yuiblog.com/blog/2006/04/11/with-statement-considered-harmful
Alan Fırtına

1
Shog, itirazlar yanlış yazılmış değişkenlerle ilgili değil, bir kod bloğuna bakmak ve o bloktaki belirli bir satırın ne yaptığını kesin olarak söyleyebilmekle ilgili. Javascript nesneleri çok dinamik olduğu için, hangi özelliklere / üyelere sahip olduğunu kesinlikle söyleyemezsiniz.
Alan Storm

2
Amin - Bulduğum herhangi bir JS'de "with" ifadesini görürsem, onu ortadan kaldırır ve neden bunu kullanmak için iyi bir şey olmadığını bildiğinden emin olmak için yazan geliştiriciyi sorgularım ... "gizli özellik?" Daha çok "beceriksiz özellik" gibi.
Jason Bunting

1
abcd ile daha karmaşık bir zincir düşünün "(abc) {d.foo = bar;} güçlü ve doğası gereği hata eğilimli değil. Anahtar kök bir seviye yukarı kısaltmaktır. Ve değişken bir isim yanlış? Eğer " nerede " olursa olsun, bunu nerede yaparsanız yapın
annakata

4
Douglas Crockford yakın zamanda "ile" bir .NET Rocks JavaScript en kötü kısımlarından biri olduğunu söyledi! dijital ses dosyası.
çekirdek

51

Yöntemler (veya işlevler) birlikte çalışmak üzere tasarlandıkları türde olmayan nesneler üzerinde çağrılabilir. Özel nesnelerde yerel (hızlı) yöntemleri çağırmak harika.

var listNodes = document.getElementsByTagName('a');
listNodes.sort(function(a, b){ ... });

Bu kod listNodes,Array

Array.prototype.sort.apply(listNodes, [function(a, b){ ... }]);

Bu kod listNodes, tarafından kullanılacak yeterli dizi benzeri özellikleri (length, [] operatörü) tanımladığı için çalışır sort().


43

Prototypal mirası (Douglas Crockford tarafından popülerleştirilmiştir) Javascript'teki birçok şey hakkında düşünme şeklinizde tamamen devrim yaratır.

Object.beget = (function(Function){
    return function(Object){
        Function.prototype = Object;
        return new Function;
    }
})(function(){});

Bu bir katil! Ne yazık ki neredeyse hiç kimse onu kullanmıyor.

Herhangi bir nesnenin yeni örneklerini "başlatmanıza", onları genişletmenize ve diğer özelliklerine (canlı) prototip bir miras bağlantısı sağlamanıza olanak tanır. Misal:

var A = {
  foo : 'greetings'
};  
var B = Object.beget(A);

alert(B.foo);     // 'greetings'

// changes and additionns to A are reflected in B
A.foo = 'hello';
alert(B.foo);     // 'hello'

A.bar = 'world';
alert(B.bar);     // 'world'


// ...but not the other way around
B.foo = 'wazzap';
alert(A.foo);     // 'hello'

B.bar = 'universe';
alert(A.bar);     // 'world'

42

Bazıları buna bir tat meselesi diyebilir, ama:

aWizz = wizz || "default";
// same as: if (wizz) { aWizz = wizz; } else { aWizz = "default"; }

Üçlü operatör, Şema'nın (koşul ...) gibi davranması için zincirlenebilir:

(cond (predicate  (action  ...))
      (predicate2 (action2 ...))
      (#t         default ))

olarak yazılabilir ...

predicate  ? action( ... ) :
predicate2 ? action2( ... ) :
             default;

Bu çok "işlevsel", çünkü yan etkileri olmadan kodunuzu dallar. Bunun yerine:

if (predicate) {
  foo = "one";
} else if (predicate2) {
  foo = "two";
} else {
  foo = "default";
}

Yazabilirsin:

foo = predicate  ? "one" :
      predicate2 ? "two" :
                   "default";

Özyineleme ile de iyi çalışır :)


Verdiğiniz sözdizimini seviyorum. Hiç böyle zincirlenmeyi düşünmemiştim. düzgün.
Allain Lalonde

2
Ah ... JavaScript'in bir switch () ifadesi var. :-)
staticsan

Anahtar ifadelerinin büyük bir hayranı değilim - bunlar fonksiyonel programlama değil C'nin bir eseridir. Örneğimde, bir switch ifadesinin, hepsi "foo =" ile başlayan üç ayrı ifadeye ihtiyacı olacaktır - bariz gereksiz tekrar.
Andrey Fedorov

14
Üçüncüsü üçlü operatörü memnuniyetle karşılıyorum.
thomasrutter

8
Yeniden okumada, bunun "kodun başka bir dil gibi görünmesini" sağlamadığını, ancak aslında kodun anlamsal anlamını basitleştirdiğini belirtmek isterim: "" şeyler "," if "ile değil" foo = ... "ile başlaması gereken bir ifadedir.
Andrey Fedorov

41

Sayılar da nesnedir. Böylece aşağıdakiler gibi harika şeyler yapabilirsiniz:

// convert to base 2
(5).toString(2) // returns "101"

// provide built in iteration
Number.prototype.times = function(funct){
  if(typeof funct === 'function') {
    for(var i = 0;i < Math.floor(this);i++) {
      funct(i);
    }
  }
  return this;
}


(5).times(function(i){
  string += i+" ";
});
// string now equals "0 1 2 3 4 "

var x = 1000;

x.times(function(i){
  document.body.innerHTML += '<p>paragraph #'+i+'</p>';
});
// adds 1000 parapraphs to the document

AMAN TANRIM! ToString (radix) hakkında bir şey bilmiyordum ...
Ateş Goral

1
Bu uygulama timesverimli değildir: Math.floorsadece bir kez yerine her seferinde çağrılır.
dolmen

33

JavaScript'teki kapanışlara ne dersiniz (C # v2.0 + 'daki anonim yöntemlere benzer). Bir işlev veya "ifade" oluşturan bir işlev oluşturabilirsiniz.

Kapaklara örnek :

//Takes a function that filters numbers and calls the function on 
//it to build up a list of numbers that satisfy the function.
function filter(filterFunction, numbers)
{
  var filteredNumbers = [];

  for (var index = 0; index < numbers.length; index++)
  {
    if (filterFunction(numbers[index]) == true)
    {
      filteredNumbers.push(numbers[index]);
    }
  }
  return filteredNumbers;
}

//Creates a function (closure) that will remember the value "lowerBound" 
//that gets passed in and keep a copy of it.
function buildGreaterThanFunction(lowerBound)
{
  return function (numberToCheck) {
    return (numberToCheck > lowerBound) ? true : false;
  };
}

var numbers = [1, 15, 20, 4, 11, 9, 77, 102, 6];

var greaterThan7 = buildGreaterThanFunction(7);
var greaterThan15 = buildGreaterThanFunction(15);

numbers = filter(greaterThan7, numbers);
alert('Greater Than 7: ' + numbers);

numbers = filter(greaterThan15, numbers);
alert('Greater Than 15: ' + numbers);

1
emin değilim, ancak (numberToCheck> lowerBound) dönebilirsiniz? doğru yanlış; basitçe return (numberToCheck> lowerBound) olur; sadece anlayışımı artırmaya çalışıyor ...
davidsleeps

4
Ben C # anonim fonksiyonları
kapanış

11
Kapaklar ve anonim işlevler ayrı, farklı kavramlardır. Bu işlevler adlandırılmadan oluşturulabilir, anonim işlevlere sahiptir. 'Create' kapsamındaki bir değişkenin yaratılan fonksiyonla bağlantılı olması bir kapanıştır. Kısacası, kapanış daha çok gizli bir global değişkene benzer.
slebetman

1
Bu doğru. Anonim yöntemler, oluşturma kapsamındaki bir değişkeni kullandığında, bu, kapatmaya benzerdir. Cevabı ingilizce güncelledim. Hala arzulanan bir şey bırakıyor, ama doğru ingilizce için kayboldum.
Tyler

2
Bunun bir kapamanın ne olduğunu anlamanın en iyi ya da en kolay yolu olduğunu düşünmüyorum. Sadece söylüyorum. Bir kapanış noktası, bir grup değişken 'kapsam dışına çıkmış gibi görünse bile, bu kapsamda başlangıçta tanımlanan bir fonksiyon için hala kullanılabilir kalabilmeleridir. Yukarıdaki örnekte bunun anlamı, dış işlev olan buildGreaterThanFunction sona erdiğinde bile, bu iç, anonim işlev tarafından hala erişilebilen anlamına gelir.
thomasrutter

32

Ayrıca sınıfları genişletebilir (devralabilir) ve bununla ilgili prototip zincir kaşığı16 kullanarak özellikleri / yöntemleri geçersiz kılabilirsiniz .

Aşağıdaki örnekte bir Pet sınıfı oluşturup bazı özellikleri tanımlarız. Ayrıca Object'den devralınan .toString () yöntemini geçersiz kılar.

Bundan sonra , Pet'i genişleten ve tekrar davranışını (polimorfizm) değiştiren .toString () yöntemini geçersiz kılan bir Dog sınıfı yaratırız . Ayrıca, alt sınıfa başka özellikler ekliyoruz.

Bundan sonra, Köpeğin hala Köpek tipi, Pet tipi ve Nesne tipi olduğunu göstermek için miras zincirini kontrol ediyoruz.

// Defines a Pet class constructor 
function Pet(name) 
{
    this.getName = function() { return name; };
    this.setName = function(newName) { name = newName; };
}

// Adds the Pet.toString() function for all Pet objects
Pet.prototype.toString = function() 
{
    return 'This pets name is: ' + this.getName();
};
// end of class Pet

// Define Dog class constructor (Dog : Pet) 
function Dog(name, breed) 
{
    // think Dog : base(name) 
    Pet.call(this, name);
    this.getBreed = function() { return breed; };
}

// this makes Dog.prototype inherit from Pet.prototype
Dog.prototype = new Pet();

// Currently Pet.prototype.constructor
// points to Pet. We want our Dog instances'
// constructor to point to Dog.
Dog.prototype.constructor = Dog;

// Now we override Pet.prototype.toString
Dog.prototype.toString = function() 
{
    return 'This dogs name is: ' + this.getName() + 
        ', and its breed is: ' + this.getBreed();
};
// end of class Dog

var parrotty = new Pet('Parrotty the Parrot');
var dog = new Dog('Buddy', 'Great Dane');
// test the new toString()
alert(parrotty);
alert(dog);

// Testing instanceof (similar to the `is` operator)
alert('Is dog instance of Dog? ' + (dog instanceof Dog)); //true
alert('Is dog instance of Pet? ' + (dog instanceof Pet)); //true
alert('Is dog instance of Object? ' + (dog instanceof Object)); //true

Bu soruya verilen her iki cevap da Ray Djajadinata'nın yazdığı harika bir MSDN makalesinden kodlardı.


31

Türlerine bağlı olarak istisnalar yakalayabilirsiniz. Alıntı sahibi MDC :

try {
   myroutine(); // may throw three exceptions
} catch (e if e instanceof TypeError) {
   // statements to handle TypeError exceptions
} catch (e if e instanceof RangeError) {
   // statements to handle RangeError exceptions
} catch (e if e instanceof EvalError) {
   // statements to handle EvalError exceptions
} catch (e) {
   // statements to handle any unspecified exceptions
   logMyErrors(e); // pass exception object to error handler
}

NOT: Koşullu catch deyimleri, ECMAScript belirtiminin bir parçası olmayan bir Netscape (ve dolayısıyla Mozilla / Firefox) uzantısıdır ve bu nedenle belirli tarayıcılar dışında güvenilemez.


29
Ben yardım edemedim: yakalamak (beni eğer canCan)
Ateş Goral

6
Belirttiğiniz MDC sayfasındaki notu okuyun: koşullu yakalama cümleleri, ECMAScript spesifikasyonunun bir parçası olmayan bir Netscape (ve dolayısıyla Mozilla / Firefox) uzantısıdır ve bu nedenle belirli tarayıcılar dışında güvenilemez.
Jason S

31

Kafamın tepesinden ...

Fonksiyonlar

arguments.callee, "arguments" değişkenini barındıran işlevi ifade eder, böylece anonim işlevleri geri almak için kullanılabilir:

var recurse = function() {
  if (condition) arguments.callee(); //calls recurse() again
}

Böyle bir şey yapmak istiyorsanız bu yararlıdır:

//do something to all array items within an array recursively
myArray.forEach(function(item) {
  if (item instanceof Array) item.forEach(arguments.callee)
  else {/*...*/}
})

Nesneler

Nesne üyeleri hakkında ilginç bir şey: isimleri olarak herhangi bir dizeye sahip olabilirler:

//these are normal object members
var obj = {
  a : function() {},
  b : function() {}
}
//but we can do this too
var rules = {
  ".layout .widget" : function(element) {},
  "a[href]" : function(element) {}
}
/* 
this snippet searches the page for elements that
match the CSS selectors and applies the respective function to them:
*/
for (var item in rules) {
  var elements = document.querySelectorAll(rules[item]);
  for (var e, i = 0; e = elements[i++];) rules[item](e);
}

Teller

String.split normal ifadeleri parametre olarak alabilir:

"hello world   with  spaces".split(/\s+/g);
//returns an array: ["hello", "world", "with", "spaces"]

String.replace normal bir ifadeyi arama parametresi olarak, işlevi de işlev parametresi olarak alabilir:

var i = 1;
"foo bar baz ".replace(/\s+/g, function() {return i++});
//returns "foo1bar2baz3"

Bahsettiğiniz şeyler ... Bunlar tüm tarayıcılarda uygulanmış mı?
cllpse

4
Hayır. Mosaic'in çoğunda olmadığından eminim.
jsight

2
Javascript özellikleri, evet, tüm büyük tarayıcılarda (IE6 / 7, FF2 / 3, Opera 9+, Safari2 / 3 ve Chrome) uygulanır. document.querySelectorAll henüz tüm tarayıcılarda desteklenmemektedir (JQuery $ () ve Prototype'in $$ () W3C sürümüdür
Leo

6
arguments.calleekullanımdan kaldırıldı ve ECMAScript 5'te atılacak ve istisna olacak.
Merhaba71

tam olarak doğru değil. Bir nesne anahtarı, yerleşik nesne yöntemini geçersiz kılacağı için "hasOwnProperty" dizesini ad olarak kullanamaz (ya da daha doğrusu kullanmamalıdır).
Breton

29

Çoğu zaman anahtar yerine nesne kullanabilirsiniz.

function getInnerText(o){
    return o === null? null : {
        string: o,
        array: o.map(getInnerText).join(""),
        object:getInnerText(o["childNodes"])
    }[typeis(o)];
}

Güncelleme: Önceden verimsiz olduğunu değerlendiren vakalardan endişe ediyorsanız (neden programın tasarımında bu kadar erken verimlilik konusunda endişelisiniz ??) o zaman böyle bir şey yapabilirsiniz:

function getInnerText(o){
    return o === null? null : {
        string: function() { return o;},
        array: function() { return o.map(getInnerText).join(""); },
        object: function () { return getInnerText(o["childNodes"]; ) }
    }[typeis(o)]();
}

Bu, bir anahtardan veya nesneden yazmak (veya okumak) için daha zahmetlidir, ancak aşağıdaki yorumlar bölümünde ayrıntılı olarak açıklanan, anahtar yerine bir nesne kullanmanın yararlarını korur. Bu tarz aynı zamanda, yeterince büyüdüğünde bunu uygun bir "sınıf" haline getirmeyi daha kolay hale getirir.

update2: ES.next için önerilen sözdizimi uzantılarıyla bu olur

let getInnerText = o -> ({
    string: o -> o,
    array: o -> o.map(getInnerText).join(""),
    object: o -> getInnerText(o["childNodes"])
}[ typeis o ] || (->null) )(o);

3
Python bir switch deyimi olmadan bu şekilde geçer.
outis

2
Sorun her zaman tüm vakaları değerlendirmesidir.
Kornel

@porneL bu doğrudur, ancak bazı faydalar sağlar: Mantıksal olarak daha temiz: Vakalar bir karmaşa üzerinde aranan dizelerdir, biri doğru olana kadar her birinin eşitlik için değerlendirilmesi gereken ifadeler değildir. Böylece daha fazla "değer" değerlendirilirken, daha az "anahtar" değerlendirilir. Nesneler dinamik olarak oluşturulabilir ve daha sonra ölçeklenebilirlik için değiştirilebilir, UI yazdırmak veya doküman oluşturmak için yansıtılabilir ve hatta kopyalanmış / yapıştırılmış vakalara sahip olmaktan daha iyi olan dinamik bir "arama" işleviyle değiştirilebilir. Aralar, düşmeler veya varsayılan değerler hakkında karışıklık yoktur. JSON serileştirilebilir ...
Breton

@porneL oh evet, ve yine ölçeklenebilirlik için, bir nesne kolayca bir harici bir yapılandırma veya veri dosyasına dönüştürülebilir, bir switch deyiminden biraz daha basit bir değişiklik olabilir - Ama akılda tutulması gereken bir nesne ile tasarlanmışsa önemsiz ile.
Breton

Bu geç bir giriş olduğunu biliyorum, ama bazı özel tip kontrol mantığı yoksa, ne zaman bir dizi hiç örnek ile işe gidiyor? var arr = []; typeof arr; // object
keeganwatkins

25

Bir nesnenin özellikleri arasında yineleme yaparken hasOwnProperty yöntemini kullandığınızdan emin olun :

for (p in anObject) {
    if (anObject.hasOwnProperty(p)) {
        //Do stuff with p here
    }
}

Bu, yalnızca anObject öğesinin doğrudan özelliklerine erişmeniz ve prototip zincirinin altındaki özellikleri kullanmamanız için yapılır.


23

Genel Arayüzlü özel değişkenler

Kendinden çağırma işlevi tanımına sahip düzgün küçük bir numara kullanır. Geri döndürülen nesnenin içindeki her şey genel arayüzde kullanılabilirken, diğer her şey özeldir.

var test = function () {
    //private members
    var x = 1;
    var y = function () {
        return x * 2;
    };
    //public interface
    return {
        setx : function (newx) {
            x = newx;
        },
        gety : function () {
            return y();
        }
    }
}();

assert(undefined == test.x);
assert(undefined == test.y);
assert(2 == test.gety());
test.setx(5);
assert(10 == test.gety());

1
Bu modül deseni olarak adlandırılır, Eric Miraglia tarafından yuiblog.com/blog/2007/06/12/module-pattern adresinde adının yanıltıcı olduğunu düşünüyorum, Singleton Kalıbı veya benzeri bir şey olarak adlandırılmalıdır. Ayrıca genel yöntemlerin 'bu' nesneyi kullanarak diğer genel yöntemleri de çağırabileceğini de ekleyebilirim. Her şeyi kodumda her zaman düzenli ve temiz tutmak için kullanıyorum.
mikeycgto
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.