Fitur Tersembunyi dari JavaScript? [Tutup]

312

Menurut Anda, "Fitur Tersembunyi" apa yang harus diketahui oleh setiap programmer?

Setelah melihat kualitas yang sangat baik dari jawaban untuk pertanyaan-pertanyaan berikut, saya pikir sudah waktunya untuk meminta JavaScript.

Meskipun JavaScript bisa dibilang adalah bahasa Sisi Klien yang paling penting saat ini (tanyakan saja pada Google), mengejutkan betapa sedikit pengembang web yang paling menghargai betapa kuatnya sebenarnya.

Binoj Antony
sumber
1
Bukankah maksud Anda, "Setelah melihat rep. Poin dan melihat pertanyaan lain ini menarik, saya pikir saya akan mengajukan pertanyaan yang persis sama untuk meningkatkan saya sendiri" ;-)
Bobby Jack
1
Tentu, pesimis. :) Saya mempertimbangkan untuk menjadikan ini pertanyaan komunitas. Juga, setelah Anda mendapatkan sejumlah poin tertentu itu semua pengembalian berkurang.
Allain Lalonde
1
Cukup adil - tidak terlihat seolah-olah Anda 'membutuhkan' perwakilan! Saya kira saya hanya memiliki masalah besar dengan C # satu - sepertinya bukan jenis pertanyaan yang menjadi tujuan situs ini.
Bobby Jack
3
Ya, mungkin tidak, tetapi saya menemukan pengetahuan dalam jawaban itu bagus. Saya pikir Anda akan sulit sekali untuk mengekspos programmer C # rata-rata untuk semua itu di satu tempat jika tidak untuk SO. Butuh bertahun-tahun bermain dengannya untuk menghasilkan daftar sulit yang sama.
Allain Lalonde
7
Saya telah menulis JavaScript secara profesional selama 10 tahun sekarang dan saya belajar satu atau tiga hal dari utas ini. Terima kasih, Alan!
Andrew Hedges

Jawaban:

373

Anda tidak perlu menentukan parameter apa pun untuk suatu fungsi. Anda bisa menggunakan argumentsobjek seperti array fungsi .

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
Mark Cidade
sumber
117
Perlu dicatat bahwa meskipun argumen bertindak seperti sebuah array, itu bukan javascript Array yang sebenarnya - itu hanya sebuah objek. Jadi Anda tidak dapat melakukan join (), pop (), push (), slice () dan sebagainya. (Anda dapat mengonversinya menjadi array nyata jika Anda ingin: "var argArray = Array.prototype.slice.call (argumen);")
Jacob Mattison
51
Perlu juga dicatat bahwa mengakses objek Argumen relatif mahal - contoh terbaik adalah di Safari, Firefox, dan Chrome nightlies di mana hanya mereferensi argumentsobjek membuat panggilan fungsi jauh lebih lambat - misalnya. jika (salah) argumen; akan melukai perf.
olliej
48
Dalam nada yang sama, argumen memiliki properti "callee" yang merupakan fungsi saat itu sendiri. Ini memungkinkan untuk melakukan rekursi dengan fungsi anonim, keren!
Vincent Robert
4
@Nathan "f (x, y, z)" terlihat lebih baik daripada "f ([x, y, z])".
Mark Cidade
16
@Vincent Robert: harap dicatat bahwa arguments.calleeitu sudah usang.
ken
204

Saya bisa mengutip sebagian besar buku hebat Douglas Crockford, JavaScript: The Good Parts .

Tapi saya akan mengambil satu untuk Anda, selalu gunakan ===dan !==bukan ==dan!=

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

==tidak transitif. Jika Anda menggunakannya ===akan memberikan false untuk semua pernyataan ini seperti yang diharapkan.

Martin Clarke
sumber
29
Sangat memalukan bahwa begitu banyak orang berpikir bahwa Crockford adalah yang paling tahu. Memang, orang itu tepat sasaran dengan sebagian besar kritiknya, tapi saya berhenti memberikan barang-barangnya dukungan seperti kebanyakan pengembang ...
Jason Bunting
21
Saya kedua peringatan Jason. Buku itu sendiri sangat menarik, dan hal ini memberikan banyak nasihat yang baik, tapi DC jauh terlalu yakin bahwa jalan melakukan sesuatu adalah satu-satunya cara yang benar, segala sesuatu yang lain adalah "cacat". Jika Anda ingin beberapa contoh, lihat tanggapannya di JSLint Yahoo Group.
Zilk
30
Gunakan === daripada == adalah saran yang baik jika Anda bingung dengan pengetikan dinamis dan hanya ingin itu "benar-benar" sama. Kita yang memahami pengetikan dinamis dapat terus menggunakan == untuk situasi di mana kita tahu kita ingin melakukan cast, seperti pada 0 == '' atau 0 == '0'.
thomasrutter
20
Yah == dan === bukan tentang pengetikan dinamis. == melakukan type coersion, yang merupakan binatang yang berbeda. Jika Anda tahu, bahwa Anda ingin melakukan cast ke string / number / etc, maka Anda harus melakukannya secara eksplisit.
Rene Saarsoo
15
Saya pikir bagian paling menakutkan ==adalah '\n\t\r ' == 0=> true...: D
Shrikant Sharat
189

Fungsi adalah warga negara kelas satu dalam JavaScript:

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

Teknik pemrograman fungsional dapat digunakan untuk menulis javascript elegan .

Khususnya, fungsi dapat dikirimkan sebagai parameter, misalnya Array.filter () menerima panggilan balik:

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

Anda juga dapat mendeklarasikan fungsi "pribadi" yang hanya ada dalam lingkup fungsi tertentu:

function PrintName() {
    var privateFunction = function() { return "Steve"; };
    return privateFunction();
}
Gulzar Nazim
sumber
3
Ada tiga cara untuk membuat fungsi dalam javascript: jumlah fungsi (x, y, z) {return (x + y + z); } dan var sum = Fungsi baru ("x", "y", "z", "return (x + y + z);"); adalah cara lain.
Marius
6
Konsep fungsi-sebagai-data pasti memenangkan poin besar dalam buku saya.
Jason Bunting
Saya baru saja memperbarui sampel untuk menunjukkan cara menggunakan fungsi "pribadi" yang hanya ada dalam lingkup fungsi tertentu.
Chris Pietschmann
new Function()sama jahatnya dengan eval. Jangan gunakan.
Nicolás
11
tidak yakin ini adalah fitur tersembunyi ... lebih seperti fitur inti.
Claudiu
162

Anda dapat menggunakan di operator untuk memeriksa apakah kunci ada dalam suatu objek:

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

Jika Anda menemukan objek literal terlalu buruk, Anda dapat menggabungkannya dengan tip fungsi tanpa parameter:

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
Mark Cidade
sumber
22
Tidak begitu pintar, yang memeriksa apakah ada kunci, bukan jika nilainya. x dalam daftar; hanya berfungsi karena x [1]! = null, bukan karena nilai 1 ada di sana.
Armin Ronacher
1
Saya belum menggunakan teknik ina sementara jadi saya lupa bahwa saya benar-benar menggunakan objek literal sebelumnya. Terima kasih atas koreksinya.
Mark Cidade
34
Juga, berhati-hatilah: operator di dalam juga menguji rantai prototipe! Jika seseorang telah meletakkan properti yang disebut '5' pada Object.prototype, contoh kedua akan mengembalikan true bahkan jika Anda memanggil '5 dalam daftar (1, 2, 3, 4)' ... Anda sebaiknya menggunakan hasOwnProperty metode: daftar (1, 2, 3, 4) .hasOwnProperty (5) akan mengembalikan false, bahkan jika Object.prototype memiliki properti '5'.
Martijn
3
Untuk solusi paling umum, yang dapat menguji apakah Obyek memiliki properti sendiri, bahkan jika itu bernama "hasOwnProperty", Anda harus pergi jauh ke: Object.prototype.hasOwnProperty.call (objek, nama) ;
Kris Kowal
1
@ Kris, tidak kecuali seseorang menimpa Object.prototype.hasOwnProperty;)
Nick
153

Menetapkan nilai default ke variabel

Anda bisa menggunakan logika atau operator ||dalam ekspresi penugasan untuk memberikan nilai default:

var a = b || c;

The avariabel akan mendapatkan nilai chanya jika badalah falsy (jika adalah null, false, undefined, 0, empty string, atau NaN), jika tidak aakan mendapatkan nilai b.

Ini sering berguna dalam fungsi, ketika Anda ingin memberikan nilai default untuk argumen jika tidak disediakan:

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

Contoh fallback IE dalam event handler:

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

Fitur bahasa berikut telah bersama kami sejak lama, semua implementasi JavaScript mendukungnya, tetapi mereka tidak menjadi bagian dari spesifikasi sampai ECMAScript Edisi 5 :

The debuggerpernyataan

Dijelaskan dalam: § 12.15 Pernyataan debugger

Pernyataan ini memungkinkan Anda untuk meletakkan breakpoints secara terprogram dalam kode Anda hanya dengan:

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

Jika debugger ada atau aktif, itu akan membuatnya segera rusak, tepat di baris itu.

Jika tidak, jika debugger tidak ada atau aktif pernyataan ini tidak memiliki efek yang dapat diamati.

Multiline String literals

Dijelaskan dalam: § 7.8.4 String Literals

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

Anda harus berhati-hati karena karakter di sebelah \ harus menjadi terminator garis, jika Anda memiliki spasi setelah \misalnya, kode akan terlihat persis sama, tetapi akan menaikkan a SyntaxError.

CMS
sumber
28
Tidak jika itu nol, jika itu dianggap salah. a = 0 || 42; akan memberi Anda 42. Ini sebanding dengan Python atau, bukan C # 's ?? operator. Jika Anda menginginkan perilaku C #, lakukan a = (b === null)? c: b;
Armin Ronacher
Ini juga berfungsi di Visual Studio juga, jika Anda mengembangkan di ASP.NET :)
chakrit
2
Saya berharap ada yang pantas || hanya untuk yang tidak ditentukan. Saya digigit oleh ini hari ini untuk 0, karena saya ingin membuat emulasi metode kelebihan beban, sehingga argumen terakhir adalah opsional dan nilai default akan digunakan sebagai gantinya.
egaga
+1 trik ini digunakan oleh cuplikan Google Analytics default. `var _gaq = _gaq || []; `; itu mencegah pengguna yang terlalu bersemangat untuk menimpa pekerjaan mereka sendiri.
Yahel
2
Saya tidak tahu tentang teknik literal string multiline. Fantastis, terima kasih.
Charlie Flowers
145

JavaScript tidak memiliki ruang lingkup blok (tetapi ia memiliki penutupan jadi mari kita sebut itu genap?).

var x = 1;
{
   var x = 2;
}
alert(x); // outputs 2
Eugene Yokota
sumber
3
Itu bagus. Ini adalah perbedaan yang sangat penting dari kebanyakan bahasa sejenis C.
Martin Clarke
9
Anda selalu dapat melakukan "var tmp = function () {/ * blok scope * /} ();". Sintaksnya jelek, tetapi berhasil.
Joeri Sebrechts
3
Atau Anda dapat menggunakan "let" jika hanya Firefox: stackoverflow.com/questions/61088/…
Eugene Yokota
10
atau hanya: (function () {var x = 2;}) (); alert (typeof x); // tidak terdefinisi
Pim Jager
@Pim: JSLint mengatakan: "Pindahkan doa ke parens yang berisi fungsi." Bersamaan dengan "Diharapkan tepat satu ruang antara 'fungsi' dan '('.".
Hello71
144

Anda dapat mengakses properti obyek dengan []bukannya.

Ini memungkinkan Anda mencari properti yang cocok dengan variabel.

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

Anda juga dapat menggunakan ini untuk mendapatkan / mengatur properti objek yang namanya bukan pengenal hukum.

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.

Beberapa orang tidak mengetahui hal ini dan akhirnya menggunakan eval () seperti ini, yang merupakan ide yang sangat buruk :

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

Ini lebih sulit untuk dibaca, lebih sulit untuk menemukan kesalahan dalam (tidak dapat menggunakan jslint), lebih lambat untuk dieksekusi, dan dapat menyebabkan eksploitasi XSS.

Patrick
sumber
eval itu jahat, meskipun jarang diperlukan
Doug Domeny
Saya tidak pernah menggunakan eval dan mengingat ketika saya menemukan ini. Itu membuat saya sangat senang.
Singkatnya, properti objek dapat diakses melalui notasi titik dan subskrip
Russ Cam
9
Sangat menarik untuk dicatat bahwa referensi-titik sebenarnya adalah sintaksis gula untuk bracketref. foo.bar, menurut spesifikasi itu, berperilaku seperti foo["bar"]. juga perhatikan bahwa semuanya adalah properti string. bahkan ketika Anda melakukan akses array,, array[4]4 dikonversi ke string (sekali lagi, setidaknya menurut ECMAScript v3 spec)
Claudiu
Saya kira setiap programmer JS harus mengetahui hal ini.
Cem Kalyoncu
144

Jika Anda mencari Google untuk referensi JavaScript yang layak pada topik tertentu, sertakan kata kunci "mdc" dalam permintaan Anda dan hasil pertama Anda akan berasal dari Pusat Pengembang Mozilla. Saya tidak membawa referensi atau buku luring apa pun. Saya selalu menggunakan trik kata kunci "mdc" untuk langsung mendapatkan apa yang saya cari. Sebagai contoh:

Google: javascript array sort mdc
(dalam kebanyakan kasus Anda dapat menghilangkan "javascript")

Pembaruan: Pusat Pengembang Mozilla telah diubah namanya menjadi Jaringan Pengembang Mozilla . Trik kata kunci "mdc" masih berfungsi, tetapi segera kita mungkin harus mulai menggunakan "mdn" .

Ates Goral
sumber
50
Wow, sumber yang bagus. Seketika lebih baik daripada w3schools jelek ...
DisgruntledGoat
11
Anda bahkan tidak perlu ke Google, jika Anda menggunakan Firefox: cukup ketik "array mdc" di bilah alamat dan tekan Enter.
Sasha Chedygov
2
bagian terbaiknya adalah bagaimana pertanyaan stack overflow ini ada di halaman pertama hasil :)
Jiaaro
5
Proposal ini: promotjs.com , inisiatif SEO akar rumput untuk mendorong hasil MDC lebih lanjut dalam hasil pencarian Google.
Yahel
3
Sekarang adalah pusat dokumen MDN, jadi kata kunci 'mdc' masih valid :)
Aleadam
143

Mungkin sedikit jelas bagi beberapa ...

Instal Firebug dan gunakan console.log ("hello"). Jauh lebih baik daripada menggunakan peringatan acak (); yang saya ingat pernah saya lakukan beberapa tahun yang lalu.

qui
sumber
12
Hanya saja, jangan lupa untuk menghapus pernyataan konsol sebelum merilis kode Anda kepada orang lain yang mungkin belum menginstal Firebug.
Chris Noe
161
log fungsi (msg) {if (console) console.log (msg) else alert (msg)}
Josh
4
Lebih baik lagi, awali pernyataan log dengan ';;;' dan kemudian minify mengurusnya untuk Anda. (Setidaknya, modul Perl yang saya gunakan memiliki fitur itu, dan mengklaim itu biasa.)
Kev
10
Josh: Itu tidak akan berfungsi karena konsol tidak didefinisikan. Anda dapat memeriksa typeof console! == "undefined" atau window.console.
Eli Grey
23
Selalu sertakan: if (typeof ('console') == 'undefined') {console = {log: function () {}}; } maka Anda dapat terus menggunakan console.log, dan itu tidak melakukan apa-apa.
gregmac
120

Metode Pribadi

Objek dapat memiliki metode pribadi.

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());
Allain Lalonde
sumber
16
Itu sebenarnya bukan fungsi pribadi - ini lebih merupakan variabel fungsi dalam lingkup lokal.
Keith
6
Benar tetapi dengan semua definisi operasional saya bisa memikirkan itu metode. Ini adalah blok kode dengan nama yang memiliki akses ke status instance dan hanya dapat dilihat oleh instance itu. Apa definisi Anda tentang metode pribadi?
Allain Lalonde
14
@ Zak, tepatnya! Sangat mudah, setelah menghabiskan bertahun-tahun bekerja dengan bahasa OO berbasis kelas, untuk melupakan bahwa mereka hanyalah satu implementasi dari konsep OO. Tentu saja, berbagai perpustakaan yang berupaya menjejalkan OO berbasis kelas ke dalam JS juga tidak membantu ...
Shog9
5
Hanya ingin tahu, apakah orang tersebut memiliki Blog Hukum? ;-)
travis
4
+1 untuk referensi pengembangan yang ditangkap
Domenic
99

Juga disebutkan dalam "Javascript: The Good Parts" Crockford:

parseInt()berbahaya. Jika Anda memberikannya string tanpa memberi tahu basis yang tepat, itu dapat mengembalikan angka yang tidak terduga. Misalnya parseInt('010')mengembalikan 8, bukan 10. Melewati basis ke parseInt membuatnya berfungsi dengan benar:

parseInt('010') // returns 8! (in FF3)
parseInt('010', 10); // returns 10 because we've informed it which base to work with.
bluefish101
sumber
13
Saat melakukan tinjauan kode, selalu cari yang ini. Meninggalkan ", 10" adalah kesalahan umum yang tidak diketahui dalam sebagian besar pengujian.
Doug Domeny
Saya terbakar oleh masalah radix bertahun-tahun yang lalu dan tidak pernah melupakan sesuatu yang sangat berlawanan dengan intuisi. Suatu hal yang bagus untuk ditunjukkan karena itu akan membuat Anda heran untuk sementara waktu.
JamesEggers
4
Mengapa tidak menggunakan Math.flooratau Number? 10 === Math.floor("010"); 10 === Number("010");mengapung:42 === Math.floor("42.69"); 42.69 === Number("42.69");
hanya seseorang
1
@Infinity Jika sudah bukan jawaban yang diposting, Anda harus. Saya tidak tahu itu sesederhana ini untuk mengesampingkan perilaku fungsi bawaan. Tentu saja, itu harus membuat seseorang melihat lebih dekat pada paket kode apa pun yang mereka pinjam dari situs lain. parseIntFungsi tidak berbahaya itu dapat dengan mudah dibuat untuk melakukan sesuatu yang tidak begitu berbahaya.
bob-the-destroyer
6
@Infinity: bagaimana dengan mendefinisikan ulang fn untuk menyoroti 'kesalahan pengkodean'? __parseInt = parseInt; parseInt = function (str, base) { if (!base) throw new Error(69, "All your base belong to us"); return __parseInt(str, base); }
JBRWilkinson
97

Fungsi adalah objek dan karenanya dapat memiliki properti.

fn = function (x) {
   // ...
}

fn.foo = 1;

fn.next = function (y) {
  //
}
VolkerK
sumber
13
Ini tip yang sangat berguna. Misalnya, Anda dapat menetapkan nilai default sebagai properti fungsi. Sebagai contoh: myfunc.delay = 100; Kemudian pengguna dapat mengubah nilai default dan semua panggilan fungsi akan menggunakan nilai default baru. Sebagai contoh: myfunc.delay = 200; myfunc ();
BarelyFitz
Berguna ... dan berbahaya!
palswim
Terlihat ceroboh, Mengapa menggunakan ini, bukan variabel?
instantsetsuna
1
@instantsetsuna: Mengapa ada variabel lain yang terpisah ? Seperti biasa ini bermuara pada "gunakan saat yang tepat / berguna" ;-)
VolkerK
91

Saya harus mengatakan fungsi self-executing.

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

Karena Javascript tidak memiliki ruang lingkup blok , Anda dapat menggunakan fungsi self-executing jika Anda ingin mendefinisikan variabel lokal:

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

Di sini, myvarapakah tidak mengganggu atau mencemari lingkup global, dan menghilang ketika fungsi berakhir.

thomasrutter
sumber
2
Apa gunanya ini? Anda mendapatkan hasil yang sama dari menempatkan peringatan di luar fungsi.
PotatoEngineer
7
Ini bukan tentang peringatan, ini tentang mendefinisikan dan menjalankan fungsi sekaligus. Anda bisa memiliki fungsi yang menjalankan sendiri mengembalikan nilai dan meneruskan fungsi sebagai param ke fungsi lain.
ScottKoon
5
@ Paul bagus untuk enkapsulasi.
Mike Robinson
22
Ini juga baik untuk pelingkupan blok.
Jim Hunziker
24
Ya, saya melampirkan semua .jsfile saya dalam fungsi self-executing anonim dan melampirkan apa pun yang saya inginkan dapat diakses secara global di dalamnya ke windowobjek. Mencegah polusi namespace global.
cdmckay
83

Ketahui berapa banyak parameter yang diharapkan oleh suatu fungsi

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

Ketahui berapa banyak parameter yang diterima oleh fungsi

function add_many_nums(){
    return arguments.length;
}    
add_many_nums(2,1,122,12,21,89); //returns 6
pramodc84
sumber
23
Tidak pernah tahu tentang bagian pertama. Bagus!
mcjabberz
1
Demikian pula Anda dapat mengetahui berapa banyak argumen yang diharapkan oleh suatu fungsi function.length.
Xavi
6
@ Xavi yang merupakan bagian pertama dari jawabannya
pramodc84
79

Berikut ini beberapa hal menarik:

  • Membandingkan NaNdengan apa pun (datar NaN) selalu salah, termasuk ==, <dan >.
  • NaN Singkatan dari Not a Number tetapi jika Anda meminta jenis itu sebenarnya mengembalikan nomor.
  • Array.sort dapat mengambil fungsi pembanding dan dipanggil oleh driver quicksort-like (tergantung pada implementasi).
  • Ekspresi reguler "konstanta" dapat mempertahankan status, seperti hal terakhir yang cocok.
  • Beberapa versi JavaScript memungkinkan Anda untuk mengakses $0, $1, $2anggota pada regex.
  • nulltidak seperti yang lain. Ini bukan objek, boolean, angka, string, atau pun bukan undefined. Agak seperti "pengganti" undefined. (Catatan: typeof null == "object")
  • Dalam konteks terluar, thismenghasilkan objek [Global] yang tidak dapat disebutkan namanya.
  • Mendeklarasikan suatu variabel dengan var, alih-alih hanya mengandalkan deklarasi variabel secara otomatis, memberikan peluang nyata pada runtime untuk mengoptimalkan akses ke variabel tersebut.
  • The withmembangun akan menghancurkan optimzations seperti
  • Nama variabel dapat berisi karakter Unicode.
  • Ekspresi reguler JavaScript sebenarnya tidak reguler. Mereka didasarkan pada regex Perl, dan dimungkinkan untuk membangun ekspresi dengan lookaheads yang membutuhkan waktu yang sangat, sangat lama untuk mengevaluasi.
  • Blok dapat diberi label dan digunakan sebagai target break. Loop dapat diberi label dan digunakan sebagai target continue.
  • Array tidak jarang. Mengatur elemen ke-1000 dari array kosong yang seharusnya diisi undefined. (tergantung pada implementasi)
  • if (new Boolean(false)) {...} akan mengeksekusi {...}blok
  • Mesin ekspresi reguler Javascript spesifik untuk implementasi: mis. Dimungkinkan untuk menulis ekspresi reguler "non-portabel".

[sedikit diperbarui dalam menanggapi komentar yang baik; silakan lihat komentar]

David Leonard
sumber
5
null sebenarnya adalah objek (khusus). typeof nullmengembalikan "objek".
Ates Goral
4
Anda juga bisa mendapatkan objek [Global] dari mana saja seperti ini: var glb = function () {return this; } ();
Zilk
2
Objek global dalam javascript di browser adalah objek jendela. Ketika dalam lingkup global melakukan: window.a == a;
Pim Jager
8
"Array tidak jarang" tergantung pada implementasinya. Jika Anda menetapkan nilai [1000] dan melihat [999], maka ya, benar undefined, tapi itu hanya nilai default yang Anda dapatkan ketika mencari indeks yang tidak ada. Jika Anda memeriksa [2000], itu juga akan terjadi undefined, tetapi itu tidak berarti Anda telah mengalokasikan memori untuk itu. Di IE8, beberapa array padat, dan beberapa jarang, tergantung pada bagaimana perasaan mesin JScript pada saat itu. Baca lebih lanjut di sini: blogs.msdn.com/jscript/archive/2008/04/08/...
Chris Nielsen
2
@Ates dan @SF: typeof mengembalikan "objek" untuk berbagai jenis. Tetapi begitu Anda tahu cara kerjanya dan jenis apa yang diidentifikasi sebagai "objek", setidaknya dapat diandalkan dan konsisten dalam implementasinya.
thomasrutter
77

Saya tahu saya terlambat ke pesta, tapi saya tidak bisa percaya +kegunaan operator belum disebutkan di luar "mengubah apa pun menjadi angka". Mungkin itu seberapa baik fitur tersembunyi itu?

// 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

Tentu saja, Anda dapat melakukan semua ini menggunakan Number(), tetapi +operator jauh lebih cantik!

Anda juga dapat menentukan nilai pengembalian numerik untuk objek dengan mengganti valueOf()metode prototipe . Konversi angka apa pun yang dilakukan pada objek itu tidak akan menghasilkan NaN, tetapi nilai pengembalian valueOf()metode:

var rnd = {
    "valueOf": function () { return Math.floor(Math.random()*1000); }
};
+rnd;               // -> 442;
+rnd;               // -> 727;
+rnd;               // -> 718;
Andy E
sumber
Anda dapat melakukannya dengan mudah 0xFFdll., Tidak perlu +"0xFF".
nyuszika7h
9
@ Nyuszika7H: Anda agak kehilangan titik, yang memaksa primitif dan objek lainnya ke angka. Tentu saja Anda bisa saja menulis 0xFF, banyak cara yang sama Anda dapat menulis 1bukan +true. Saya menyarankan agar Anda dapat menggunakannya +("0x"+somevar)sebagai alternatif parseInt(somevar, 16), jika Anda mau.
Andy E
75

" Metode ekstensi dalam JavaScript " melalui properti prototipe.

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

Ini akan menambahkan containsmetode ke semua Arrayobjek. Anda dapat memanggil metode ini menggunakan sintaks ini

var stringArray = ["foo", "bar", "foobar"];
stringArray.contains("foobar");
sendok16
sumber
18
Ini umumnya dianggap ide yang buruk, karena kode lain (bukan milik Anda) dapat membuat asumsi tentang objek Array.
Chris Noe
39
Itu juga umumnya dianggap ide yang buruk untuk membuat asumsi tentang objek Array. :(
kelopak mata
Uhmmmm .. javascript 1.6 array ekstra? Indeks? membunyikan lonceng?
Breton
2
@Reton: Ini bukan sesuatu yang spesifik untuk kelas Array, itu hanya sebuah contoh. Saya menggunakan ini untuk memperpanjang Date baru (). ToString (); metode, memungkinkan untuk menggunakan string mask. Setiap objek dapat diperpanjang, dan semua contoh itu mendapatkan metode baru.
Esteban Küber
1
@Mathias: ini bukan tentang DOM.
dolmen
60

Untuk menghapus properti dari objek dengan benar, Anda harus menghapus properti alih-alih hanya mengaturnya menjadi tidak terdefinisi :

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

obj.prop2 = undefined;

for (var key in obj) {
    ...

Prop2 properti masih akan menjadi bagian dari iterasi. Jika Anda ingin sepenuhnya menghilangkan prop2 , Anda sebaiknya melakukan:

delete obj.prop2;

Prop2 properti tidak akan lagi muncul saat Anda mengulangi properti.

Makan Goral
sumber
3
Perhatikan bahwa pernyataan penghapusan bukan tanpa kebiasaan khusus browsernya. Misalnya ini akan gagal dengan kesalahan besar jika Anda mencobanya di IE dan objek tersebut bukan objek JS asli (bahkan ketika menghapus properti yang Anda tambahkan sendiri). Itu juga tidak dimaksudkan untuk menghapus variabel, seperti pada delete myvar; tapi saya pikir itu berfungsi di beberapa browser. Kode dalam jawaban di atas tampaknya cukup aman.
thomasrutter
omong-omong, undefined bisa menjadi variabel juga! Coba var undefined = "something"
Johann Philipp Strathausen
57

with.

Ini jarang digunakan, dan terus terang, jarang bermanfaat ... Tapi, dalam keadaan terbatas, memang ada kegunaannya.

Misalnya: objek literal cukup berguna untuk mengatur properti dengan cepat pada objek baru . Tetapi bagaimana jika Anda perlu mengubah setengah dari properti pada objek yang ada?

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

// ...

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

Alan Storm menunjukkan bahwa ini bisa agak berbahaya: jika objek yang digunakan sebagai konteks tidak memiliki salah satu properti yang ditugaskan, itu akan diselesaikan dalam lingkup luar, mungkin membuat atau menimpa variabel global. Ini sangat berbahaya jika Anda terbiasa menulis kode untuk bekerja dengan objek di mana properti dengan nilai default atau kosong dibiarkan tidak terdefinisi:

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

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

Oleh karena itu, mungkin ide yang baik untuk menghindari penggunaan withpernyataan untuk penugasan tersebut.

Lihat juga: Apakah ada kegunaan sah untuk pernyataan "dengan" JavaScript?

Shog9
sumber
29
Kearifan konvensional statment harus dihindari. Jika objek pengguna tidak memiliki salah satu properti yang Anda sebutkan, variabel di luar pseudo-scope blok akan dimodifikasi. Dengan begitu terletak bug. Info lebih lanjut di yuiblog.com/blog/2006/04/11/with-statement-considered-harmful
Alan Storm
1
Shog, keberatannya bukan tentang variabel yang salah eja, mereka tentang melihat blok kode, dan bisa mengatakan dengan pasti apa yang dilakukan baris tertentu di blok itu. Karena objek Javascript sangat dinamis, Anda tidak dapat mengatakan dengan pasti properti / anggota yang dimilikinya setiap saat.
Alan Storm
2
Amin - jika saya melihat pernyataan "dengan" di JS apa pun yang saya temukan, saya akan menghilangkannya dan mempertanyakan pengembang yang menulisnya untuk memastikan dia tahu mengapa itu bukan Hal Baik untuk menggunakannya ... "fitur tersembunyi?" Lebih mirip "fitur menjijikkan."
Jason Bunting
1
pertimbangkan rantai abcd yang lebih kompleks "dengan (abc) {d.foo = bar;} kuat dan tidak rentan terhadap kesalahan. Kuncinya adalah untuk membatasi root satu tingkat ke atas. Dan salah mengeja nama variabel? Anda sedang memperkenalkan bug jika Anda melakukannya di mana pun Anda melakukannya, terlepas dari "dengan".
annakata
4
Douglas Crockford baru-baru ini mengatakan "dengan" adalah salah satu bagian terburuk dari JavaScript di .NET Rocks! podcast.
core
51

Metode (atau fungsi) dapat dipanggil pada objek yang bukan tipe yang dirancang untuk bekerja dengannya. Ini bagus untuk memanggil metode asli (cepat) pada objek kustom.

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

Kode ini macet karena listNodesbukanArray

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

Kode ini berfungsi karena listNodesmendefinisikan cukup properti mirip array (panjang, [] operator) untuk digunakan oleh sort().

Vincent Robert
sumber
43

Warisan prototipe (dipopulerkan oleh Douglas Crockford) sepenuhnya merevolusi cara Anda berpikir tentang banyak hal dalam Javascript.

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

Itu pembunuh! Sayang sekali hampir tidak ada yang menggunakannya.

Ini memungkinkan Anda untuk "membuat" contoh baru dari objek apa pun, memperluasnya, sambil mempertahankan tautan pewarisan prototipikal (langsung) ke properti lainnya. Contoh:

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'
Már Örlygsson
sumber
42

Beberapa akan menyebut ini masalah selera, tetapi:

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

Operator triner dapat dirantai untuk bertindak seperti Skema (kond ...):

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

dapat ditulis sebagai ...

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

Ini sangat "fungsional", karena percabangan kode Anda tanpa efek samping. Jadi alih-alih:

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

Kamu bisa menulis:

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

Bekerja dengan baik dengan rekursi juga :)

Andrey Fedorov
sumber
Saya suka sintaksis predikat yang Anda berikan. Saya tidak pernah berpikir untuk merantai seperti itu. rapi.
Allain Lalonde
2
Eh ... JavaScript memang memiliki pernyataan switch (). :-)
staticsan
Saya bukan penggemar pernyataan switch - mereka adalah artefak dari C, bukan pemrograman fungsional. Dalam contoh saya, pernyataan switch masih membutuhkan tiga pernyataan terpisah, semuanya dimulai dengan "foo =" - pengulangan yang jelas tidak perlu.
Andrey Fedorov
14
Saya, misalnya, menyambut operator ternary.
thomasrutter
8
Saat membaca ulang, saya ingin menunjukkan bahwa ini bukan "membuat kode terlihat seperti bahasa lain", tetapi sebenarnya menyederhanakan makna semantik kode: ketika Anda mencoba mengatakan "set foo ke salah satu dari tiga hal ", itu pernyataan yang harus dimulai dengan" foo = ... ", bukan" jika ".
Andrey Fedorov
41

Angka juga benda. Jadi Anda dapat melakukan hal-hal keren seperti:

// 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
Zach
sumber
OH TUHAN! Saya tidak tahu tentang toString (radix) ...
Ates Goral
1
Implementasi timesyang tidak efisien: Math.floordipanggil setiap kali, bukan hanya sekali.
dolmen
33

Bagaimana dengan penutupan dalam JavaScript (mirip dengan metode anonim di C # v2.0 +). Anda dapat membuat fungsi yang membuat fungsi atau "ekspresi".

Contoh penutupan :

//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);
Tyler
sumber
1
Saya tidak yakin, tetapi dapat kembali (numberToCheck> lowerBound)? benar salah; cukup menjadi kembali (numberToCheck> lowerBound); hanya mencoba untuk meningkatkan pemahaman saya ...
davidsleeps
4
Aku akan mengatakan fungsi anonim di C # setara penutupan, bukan sebaliknya :)
vava
11
Penutupan dan fungsi anonim adalah konsep yang terpisah dan berbeda. Fungsi-fungsi itu dapat dibuat tanpa dinamai memiliki fungsi anonim. Bahwa variabel dalam lingkup 'penciptaan' terkait dengan fungsi yang dibuat adalah penutupan. Singkatnya, penutupan lebih seperti variabel global tersembunyi.
Slebetman
1
Itu benar. Hanya ketika metode anonim menggunakan variabel dari lingkup pembuatan, itu mirip dengan penutupan. Saya telah memperbarui bahasa Inggris pada jawabannya. Masih menyisakan sesuatu yang diinginkan, tetapi saya bingung dengan bahasa Inggris yang benar.
Tyler
2
Saya tidak berpikir ini adalah contoh terbaik atau termudah untuk memahami apa itu penutupan. Hanya mengatakan. Inti dari penutupan adalah bahwa bahkan ketika sekelompok variabel muncul untuk 'keluar dari ruang lingkup' mereka masih dapat tetap tersedia untuk fungsi yang awalnya didefinisikan dalam ruang lingkup itu. Dalam contoh di atas, itu berarti variabel lowerBound masih dapat diakses oleh fungsi dalam, anonim bahkan ketika fungsi luar, buildGreaterThanFunction, berakhir.
thomasrutter
32

Anda juga dapat memperluas (mewarisi) kelas dan menimpa properti / metode menggunakan sendok rantai prototipe16 disinggung.

Dalam contoh berikut ini kita membuat Pet kelas dan mendefinisikan beberapa properti. Kami juga mengganti metode .toString () yang diwarisi dari Object.

Setelah ini kita membuat kelas Dog yang memperluas Pet dan menimpa metode .toString () lagi-lagi mengubah perilaku itu (polimorfisme). Selain itu kami menambahkan beberapa properti lainnya ke kelas anak.

Setelah ini, kami memeriksa rantai pewarisan untuk menunjukkan bahwa Anjing masih berjenis Anjing, berjenis Pet, dan berjenis Obyek.

// 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

Kedua jawaban untuk pertanyaan ini adalah kode yang dimodifikasi dari artikel MSDN yang bagus oleh Ray Djajadinata.

Tyler
sumber
31

Anda dapat menangkap pengecualian tergantung pada jenisnya. Dikutip dari 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
}

CATATAN: Klausa tangkapan bersyarat adalah ekstensi Netscape (dan karenanya Mozilla / Firefox) yang bukan bagian dari spesifikasi skrip ECMAS dan karenanya tidak dapat diandalkan kecuali pada browser tertentu.

Ionuț G. Stan
sumber
29
Saya tidak bisa menahannya: catch (me if youCan)
Ates Goral
6
Baca catatan dari halaman MDC yang Anda kutip: klausa tangkapan bersyarat adalah ekstensi Netscape (dan karenanya Mozilla / Firefox) yang bukan bagian dari spesifikasi ECMAScript dan karenanya tidak dapat diandalkan kecuali pada browser tertentu.
Jason S
31

Dari atas kepala saya...

Fungsi

arguments.callee merujuk ke fungsi yang meng-host variabel "argumen", sehingga dapat digunakan untuk kambuh fungsi anonim:

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

Itu berguna jika Anda ingin melakukan sesuatu seperti ini:

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

Benda

Hal yang menarik tentang anggota objek: mereka dapat memiliki string apa pun sebagai nama mereka:

//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);
}

String

String.split dapat menggunakan ekspresi reguler sebagai parameter:

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

String.replace dapat mengambil ekspresi reguler sebagai parameter pencarian dan fungsi sebagai parameter pengganti:

var i = 1;
"foo bar baz ".replace(/\s+/g, function() {return i++});
//returns "foo1bar2baz3"
Leo
sumber
Hal-hal yang Anda sebutkan ... Apakah diterapkan di semua browser?
cllpse
4
Tidak. Saya cukup yakin bahwa Mosaik kekurangan sebagian besar dari mereka.
jsight
2
Fitur javascript, ya, mereka diimplementasikan di semua browser utama (IE6 / 7, FF2 / 3, Opera 9+, Safari2 / 3 dan Chrome). document.querySelectorAll belum didukung di semua browser (ini adalah versi W3C dari JQuery's $ (), dan $$ Prototype's ())
Leo
6
arguments.calleesudah usang dan akan melempar dan pengecualian dalam ECMAScript 5.
Hello71
tidak sepenuhnya benar. Kunci objek tidak dapat (atau lebih tepatnya, tidak boleh) menggunakan string "hasOwnProperty" sebagai nama, karena itu akan menggantikan metode objek bawaan.
Breton
29

Anda dapat menggunakan objek alih-alih beralih sebagian besar waktu.

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

Pembaruan: jika Anda khawatir tentang kasus yang dinilai sebelumnya tidak efisien (mengapa Anda khawatir tentang efisiensi ini sejak awal dalam desain program ??) maka Anda dapat melakukan sesuatu seperti ini:

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)]();
}

Ini lebih berat untuk mengetik (atau membaca) daripada switch atau objek, tetapi mempertahankan manfaat menggunakan objek daripada switch, yang dirinci di bagian komentar di bawah ini. Gaya ini juga membuatnya lebih mudah untuk mengubah ini menjadi "kelas" yang tepat setelah cukup dewasa.

update2: dengan ekstensi sintaks yang diusulkan untuk ES.next, ini menjadi

let getInnerText = o -> ({
    string: o -> o,
    array: o -> o.map(getInnerText).join(""),
    object: o -> getInnerText(o["childNodes"])
}[ typeis o ] || (->null) )(o);
Breton
sumber
3
Begitulah cara Python bertahan tanpa pernyataan switch.
outis
2
Masalahnya adalah selalu mengevaluasi semua kasus.
Kornel
@porneL ini benar, tetapi memberikan beberapa manfaat: Logikanya lebih bersih: Kasus-kasus adalah string yang dicari pada hashtable, bukan ekspresi yang masing-masing harus dievaluasi untuk kesetaraan sampai satu kembali benar. Jadi, sementara lebih banyak "nilai" dievaluasi, lebih sedikit "kunci" dievaluasi. Objek dapat dihasilkan secara dinamis, dan dimodifikasi untuk skalabilitas nanti, tercermin untuk mencetak UI, atau menghasilkan dokumen, dan bahkan diganti dengan fungsi "pencarian" dinamis, yang lebih baik daripada memiliki kasus salin / tempel. Tidak ada kebingungan tentang break, fall-throughs, atau nilai default. Dapat berupa serial JSON ...
Breton
@porneL oh yeah, dan sekali lagi untuk skalabilitas, sebuah objek bahkan dapat dengan mudah dipintal menjadi konfigurasi eksternal atau file data, perubahan yang agak lebih mudah daripada dengan pernyataan switch- Tapi sepele jika dirancang dengan objek dalam pikiran untuk memulai dengan.
Breton
saya tahu ini adalah entri yang terlambat, tetapi kecuali jika Anda memiliki logika pengecekan tipe kustom, kapan array akan bekerja dengan contoh Anda? var arr = []; typeof arr; // object
keeganwatkins
25

Pastikan untuk menggunakan metode hasOwnProperty ketika melakukan iterasi melalui properti objek:

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

Ini dilakukan agar Anda hanya akan mengakses properti langsung dari anObject , dan tidak menggunakan properti yang berada di bawah rantai prototipe.

Andreas Grech
sumber
23

Variabel pribadi dengan Antarmuka Umum

Ini menggunakan trik kecil yang rapi dengan definisi fungsi self-calling. Segala sesuatu di dalam objek yang dikembalikan tersedia di antarmuka publik, sementara yang lainnya bersifat pribadi.

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());
Chris MacDonald
sumber
1
ini disebut pola modul, sebagaimana dijuluki oleh Eric Miraglia di yuiblog.com/blog/2007/06/12/module-pattern Saya pikir namanya menyesatkan, harus disebut Pola Singleton atau semacamnya. Saya mungkin juga menambahkan bahwa metode publik juga dapat memanggil metode publik lainnya dengan menggunakan objek 'ini'. Saya menggunakan pola ini sepanjang waktu dalam kode saya untuk menjaga semuanya teratur dan bersih.
mikeycgto