Đường cú pháp javascript tốt nhất


81

Đây là một số đá quý:

Chữ viết:

var obj = {}; // Object literal, equivalent to var obj = new Object();
var arr = []; // Array literal, equivalent to var arr = new Array();
var regex = /something/; // Regular expression literal, equivalent to var regex = new RegExp('something');

Mặc định:

arg = arg || 'default'; // if arg evaluates to false, use 'default', which is the same as:
arg = !!arg ? arg : 'default';

Tất nhiên chúng ta biết các hàm ẩn danh, nhưng có thể coi chúng như các ký tự và thực thi chúng ngay tại chỗ (như một lệnh đóng) là điều tuyệt vời:

(function() { ... })(); // Creates an anonymous function and executes it

Câu hỏi: Những cú pháp tuyệt vời nào khác có sẵn trong javascript?


2
Tôi đã không biết về điều đó || cú pháp giá trị mặc định. Đẹp và nhỏ gọn, mặc dù không quá trực quan. (Có lẽ tôi đã nhìn thấy nó, nhưng không bao giờ hiểu nó.)
Chris Noe

1
Tôi đã gặp khó khăn hơn nhiều trong việc nắm bắt cú pháp bậc ba. Nó sẽ giống như bản chất thứ hai sau khi bạn viết nó một vài lần. Đối với những nơi bạn có thể đã thấy nó, tôi nghĩ rằng cả jquery.js và prototype.js đều sử dụng nó.
mí mắt

1
Làm thế nào về việc giải thích từng ví dụ?
pc1oad1etter 22/10/08

2
Tôi không biết về "arg || 'default'". Tôi mong đợi nó trả về một giá trị boolean, nhưng nó trả về giá trị đầu tiên (từ bên trái) đánh giá thành true (tương tự như python)! Nó tốt hơn nhiều so với "arg = arg? Arg: 'default'"!
Jamol

Chris Noe đã mở chủ đề này!
Mahesh Velaga

Câu trả lời:


58

Nhận ngày giờ hiện tại dưới dạng mili giây:

Date.now()

Ví dụ: để tính thời gian thực thi một đoạn mã:

var start = Date.now();
// some code
alert((Date.now() - start) + " ms elapsed");

Trên thực tế, đây là đường cú pháp javascript tốt nhất. A winnar si yuo.
mí mắt

3
OrbMan, điều đó có thể phụ thuộc vào ngữ cảnh; nếu truyền nó như một đối số, nó có thể bị ép buộc đối với một Đối tượng hơn là một Số hoặc một Chuỗi, trong trường hợp đó, dấu + đã buộc nó thành một Số. Trên thực tế, + dường như hoạt động như một cách viết tắt của parseInt (giá trị, 10).
mí mắt,

Sửa lại: nó có một số khác biệt so với parseInt (giá trị, 10). Ví dụ: + [3] và parseInt ([3], 10) đều bằng số 3, nhưng + [3, 4] == NaN và parseInt ([3, 4], 10) == 3.
eyelidlessness

Ơ ... tất cả các trường hợp của parseInt (value, 10) phải là parseFloat (value). Và Chris Noe, xin lỗi vì spam bình luận;)
mí mắt,

1
Sự tò mò của tôi đã thúc đẩy tôi thử nó trong jsperf và có vẻ như người hoạt động tốt nhất là getTime chuẩn () :) (ref. Jsperf.com/millisecondsdate )
sirLisko

33

Kiểm tra thành viên đối tượng:

var props = {a: 1, b: 2};

("a" trong props) // true
("b" trong đạo cụ) // true
("c" trong đạo cụ) // false

Điều đó chắc chắn ngắn gọn hơn props.a === undefined Cảm ơn.
mí mắt

15
Và nó đúng ngay cả khi props = {a: undefined}.
ephemient

FYI - Firefox ném ra một TypeError khi bạn cố gắng sử dụng "in" trên một đối tượng XPCNativeWrapper. Và bắt đầu với Firefox 4, rất nhiều đối tượng được bao bọc. Vì vậy, trở lại nó trở lại props.a === không xác định trong những trường hợp đó.
Chris Noe

26

Trong Mozilla (và theo báo cáo là IE7), bạn có thể tạo một hằng số XML bằng cách sử dụng:

var xml = <elem> </elem>;

Bạn cũng có thể thay thế các biến:

var elem = "html";
var text = "Một số văn bản";
var xml = <{elem}> {text} </ {elem}>;

Có thật không? Có những động cơ khác hỗ trợ điều đó không?
mí mắt.

1
Chỉ tự hỏi: bạn có thể làm gì với biến "xml" đó khi bạn đã tạo nó? Bây giờ chỉ chơi với nó trong firebug, có vẻ như nó không có bất kỳ phương thức hoặc thuộc tính nào và bạn không thể thêm nó vào DOM.
nickf 8/10/08


8
Các ký tự E4X là một thảm họa bảo mật do các cuộc tấn công bao gồm tập lệnh chéo trang web và thực sự không tốt hơn đáng chú ý là chỉ có thể nói “var xml = new XML ('<elem> </elem>')" IMO.
bobince

2
@CharlieSomerville Đó không phải là rủi ro. E4X có khả năng biến các tệp ML 'an toàn' [X] [HT] ML thành JS hoạt động. Vui lòng đọc code.google.com/p/doctype/wiki/ArticleE4XSecurity để biết thông tin cơ bản về vấn đề này.
bobince

26

Sử dụng các hàm ẩn danh và một bao đóng để tạo một biến riêng (ẩn thông tin) và các phương thức get / set được liên kết:

var getter, setter;

(function()
{
   var _privateVar=123;
   getter = function() { return _privateVar; };
   setter = function(v) { _privateVar = v; };
})()

mất một lúc, nhưng tôi đã hiểu. điều này thật gọn gàng.
matt lohkamp 9/10/08

Tôi đã phát hiện ra một kỹ thuật tương tự cách đây một lúc trong khi xem qua nguồn swfobject. Sử dụng các bao đóng để tạo các biến / phương thức riêng là điều mà tôi có lẽ chưa bao giờ nghĩ đến. Nó khá tuyệt.
Herms

Với phiên bản JS mới, chúng ta có thể sử dụng đơn giản hơnif(true) { let _privateVar=123; }
Kulvar

Hãy lưu ý về vấn đề tiềm năng của phong cách "bóng chó" ở đây. Xem: twitter.com/paul_irish/status/176187448420864000?lang=vi
Jonathan.Brink

22

Có thể mở rộng các loại JavaScript gốc thông qua kế thừa nguyên mẫu.

String.prototype.isNullOrEmpty = function(input) {
    return input === null || input.length === 0;
}

6
Chỉ cần tránh làm điều này với Array: stackoverflow.com/questions/61088/…
Chris Noe 8/10/08

Điều này đúng, nhưng chỉ khi bạn sử dụng vòng lặp for (a in b). Thông thường, tôi sử dụng các khuôn khổ, vì tôi chắc chắn rằng mọi người khác cũng vậy. Kết quả là tôi thường sử dụng .each ()
steve_c

Đó là một vấn đề tiềm ẩn nếu bất kỳnào trong vùng chứa của bạn sử dụng cho (a trong b). Và khi vùng chứa đó là một trình duyệt, bạn có thể phá vỡ mã khác trong trình duyệt của mình, (ví dụ: khung công tác đó). Tôi đã bị đắm chìm bởi một trong những.
Chris Noe 8/10/08

Vâng. Điểm tốt, Chris. Tôi vẫn đếm thừa kế nguyên chủng là một trong những tính năng tốt nhất của JavaScript :)
steve_c

for (var i in obj) {if (! obj.hasOwnProperty (i)) {continue; } ...}
mí mắt

21

Sử dụng ===để so sánh giá trị loại:

var i = 0;
var s = "0";

if (i == s) // true

if (i === s) // sai

Nó thực sự được gọi là nghiêm ngặt bằng - về cơ bản nó tránh tất cả các chuyển đổi loại mà nếu không phải xảy ra khi thực hiện ==
olliej

các ngôn ngữ khác (PHP) cũng gọi nó là kiểm tra "danh tính", tức là: hai giá trị này có giống nhau không?
nickf 8/10/08

@nickf, có một chút nhầm lẫn. $var1 = 'string'; $var2 = 'string'; $var1 === $var2; // true, mặc dù $var1$var2không giống nhau (tham chiếu đến cùng một giá trị được lưu trữ trong bộ nhớ), chỉ là cùng một kiểu và cùng một giá trị.
mí mắt

@eyelidless, tôi không chắc rằng javascript hoạt động theo cách đó ... các chuỗi (thường) được lưu trữ và chuyển theo giá trị. Đối tượng tuy nhiên được lưu trữ như một tài liệu tham khảo: var1 = {a : 'b'}; var2 = {a : 'b'}; var1 === var2 // false.
nickf 19/12/10

@nickf, tôi hiểu điều đó. Nhưng bạn có thể xóa dấu hiệu trong mã PHP và nhận được kết quả tương tự trong JavaScript. Các chuỗi đó không giống nhau , nhưng giá trị của chúng là.
mí mắt

21

Chuỗi nhiều dòng:

var str = "Đây là \
tất cả một \
chuỗi.";

Vì bạn không thể thụt lề các dòng tiếp theo mà không thêm khoảng trắng vào chuỗi, nên mọi người thường thích nối với toán tử cộng. Nhưng điều này cung cấp một khả năng tài liệu tốt ở đây .


2
Cảnh báo công bằng - một ngoại lệ sẽ được ném ra nếu có bất kỳ khoảng trắng nào ở cuối sau dấu \.
Daniel Szabo

21

Thay đổi kích thước chiều dài của một mảng

thuộc tính độ dài không phải là chỉ đọc . Bạn có thể sử dụng nó để tăng hoặc giảm kích thước của một mảng.

var myArray = [1,2,3];
myArray.length // 3 elements.
myArray.length = 2; //Deletes the last element.
myArray.length = 20 // Adds 18 elements to the array; the elements have the empty value. A sparse array.

1
Thưa ông, đây phải là câu trả lời quan trọng nhất trên SO, tôi tin như vậy. Không phải pushing cho tôi nữa, hehe. Cảm ơn nhiều.
aefxx

4
trên thực tế, các phần tử được tạo bằng cách này không thực sự tồn tại (chúng cũng không có giá trị không xác định, nhưng việc truy cập chúng sẽ khiến bạn không xác định được). Bạn cũng không thể lặp lại chúng với for..in.
yorick

16

Lặp lại một chuỗi chẳng hạn như "-" một số lần cụ thể bằng cách tận dụng phương thức nối trên một mảng trống:

var s = new Array(repeat+1).join("-");

Kết quả bằng "---" khi lặp lại == 3.


15

Giống như toán tử mặc định, ||là toán tử bảo vệ , &&.

answer = obj && obj.property

như trái ngược với

if (obj) {
    answer = obj.property;
}
else {
    answer = null;
}

1
Nó không nhất thiết phải như vậy null. Đây chỉ là trường hợp khi obj === null.
pimvdb,

1
Cũng có thể được sử dụng kết hợp với || để đảm bảo sao lưu trong trường hợp obj hoàn toàn không tồn tại HOẶC đối tượng tồn tại nhưng thuộc tính khóa thì không. Theo cách này, câu trả lời luôn được xác định: answer = (obj && obj.property) || 'backupprop';
Dtipson

13
var tags = {
    name: "Jack",
    location: "USA"
};

"Name: {name}<br>From {location}".replace(/\{(.*?)\}/gim, function(all, match){
    return tags[match];
});

callback để thay thế chuỗi chỉ hữu ích.


12

Getters và setters :

function Foo(bar)
{
    this._bar = bar;
}

Foo.prototype =
{
    get bar()
    {
        return this._bar;
    },

    set bar(bar)
    {
        this._bar = bar.toUpperCase();
    }
};

Cung cấp cho chúng tôi:

>>> var myFoo = new Foo("bar");
>>> myFoo.bar
"BAR"
>>> myFoo.bar = "Baz";
>>> myFoo.bar
"BAZ"

Vâng, nó sẽ đẹp hơn một chút so với cách tiếp cận hiện tại mà tôi đã sử dụng.
Ash

@eyelidless nó nằm trong Object.defineProperty của ECMAScript 5 mà IE triển khai và các trình duyệt khác có thể sử dụng defineGetter .
Eli Grey

IE8 chỉ cụ getters / setters cho đối tượng DOM, do đó, nó vô dụng khi nói đến làm API đối tượng của riêng bạn gọn gàng: - /
Jonny Buchanan

5

Đây không phải là một javascript độc quyền, nhưng lưu như ba dòng mã:

check ? value1 : value2

Có tương đương với điều này khi không chỉ định giá trị (ví dụ: fnName? FnName: defaultFn;) không?
mí mắt

1
Không, toán tử bậc ba hoàn toàn dành cho các biểu thức; không có tuyên bố
Josh Hinman 8/10/08

1
bạn có thể sử dụng nó để đánh giá các hàm ẩn danh, như sau: "var myFunc = (browserIsIE? function () {...}: function () {...})". cá nhân tôi sẽ không giới thiệu nó vì nó khá khó hiểu, nhưng ít nhất nó có thể.
nickf 8/10/08

"Đánh giá" có lẽ không phải là từ tốt nhất trong nhận xét trước đó. Ừm .. chỉ định?
nickf 8/10/08

@eyelidless: Vâng: fnName? fnName (): defaultFn (); // trên một dòng riêng, tác phẩm của mình
Ates Goral

4

Thêm một chút về ví dụ của levik:

var foo = (condition) ? value1 : value2;

4
Bạn không cần dấu ngoặc đơn. Toán tử bậc ba cũng phổ biến cho nhiều ngôn ngữ khác.
Ates Goral

1
Dấu ngoặc đơn giúp ích khi có sự mơ hồ về cú pháp trong câu lệnh điều kiện (ví dụ: xác định thành phần nào của câu lệnh điều kiện? Áp dụng cho).
mí mắt,


4

Đang theo dõi obj || Cú pháp {default: true}:

gọi hàm của bạn với điều này: hello (needOne && needTwo && needThree) nếu một tham số không được xác định hoặc sai thì nó sẽ gọi hello (false), đôi khi hữu ích


4

Trong các tình huống phân tích cú pháp với một nhóm các bộ phận thành phần cố định:

var str = "John Doe";

Bạn có thể gán kết quả trực tiếp vào các biến, bằng cách sử dụng synatx "chuyển nhượng cơ cấu":

var [fname, lname] = str.split(" ");
alert(lname + ", " + fname);

Cái nào dễ đọc hơn một chút so với:

var a = str.split(" ");
alert(a[1] + ", " + a[0]);

Thay thế:

var [str, fname, lname] = str.match(/(.*) (.*)/);

Lưu ý rằng đây là một tính năng Javascript 1.7 . Vì vậy, đó là trình duyệt Mozilla 2.0+ và Chrome 6+, tại thời điểm này.


Tôi đã thử điều này trong bảng điều khiển Javascript của Safari và nó dẫn đến lỗi phân tích cú pháp.
mí mắt

Snap, tôi đoán tôi chỉ sử dụng cái này trong Firefox. Tôi đã thêm một ghi chú về khả năng tương thích của trình duyệt.
Chris Noe

Nó không hoạt động trên Chrome 6. Nó mang lại SyntaxError: Unexpected token [.
RaYell 13/10/10

Một nghiên cứu nhỏ bắt đầu tiết lộ rằng phiên bản 1.7 của chrome không hoàn toàn là tiêu chuẩn. Báo cáo cũng có vấn đề với let: stackoverflow.com/questions/300185/…
Chris Noe,

Nó vẫn không hoạt động trên Chrome 13. Bất kỳ manh mối nào về thời điểm điều này sẽ được triển khai?
pimvdb,

3

Chức năng Mũi tên được Gọi ngay lập tức:

var test = "hello, world!";
(() => test)(); //returns "hello, world!";

2

Tôi quên mất:

(function() { ... }).someMethod(); // Functions as objects

2

Tạo một đối tượng ẩn danh theo nghĩa đen chỉ với: ({})

Ví dụ: cần biết nếu các đối tượng có phương thức valueOf:

var hasValueOf = !! ({}). valueOf

Bonus theo cú pháp: the double-not '!!' để chuyển đổi khá nhiều thứ thành Boolean rất ngắn gọn.


1

Tôi thích có thể đánh giá () một chuỗi json và lấy lại cấu trúc dữ liệu được điền đầy đủ. Tôi ghét phải viết mọi thứ ít nhất hai lần (một lần cho IE, một lần nữa cho Mozilla).


1

Gán các từ khóa thường dùng (hoặc bất kỳ phương pháp nào) cho các biến đơn giản như ths

  var $$ = document.getElementById;

  $$('samText');

3
Điều đó sẽ không hoạt động (ít nhất là trong Chrome), vì thisgiá trị bị mất. Thay vào đó, bạn nên sử dụng document.getElementById.bind(document). Nếu không có bindnó chỉ là gán HTMLDocument.prototype.getElementByIdchức năng, không có thông tin mà nó nên được gọi document.
pimvdb,

1

Lớp Ngày của JavaScript cung cấp bán "Giao diện Thông thạo". Điều này giải thích cho việc không thể trích xuất phần ngày từ lớp Ngày trực tiếp:

var today = new Date((new Date()).setHours(0, 0, 0, 0));

Nó không phải là một Giao diện Thông thạo hoàn toàn vì phần sau sẽ chỉ cung cấp cho chúng ta một giá trị số mà không thực sự là một đối tượng Ngày:

var today = new Date().setHours(0, 0, 0, 0);

1

Dự phòng mặc định:

var foo = {}; // empty object literal

alert(foo.bar) // will alert "undefined"

alert(foo.bar || "bar"); // will alert the fallback ("bar")

Một ví dụ thực tế:

// will result in a type error
if (foo.bar.length === 0)

// with a default fallback you are always sure that the length
// property will be available.
if ((foo.bar || "").length === 0) 

1

Đây là một trong những tôi vừa phát hiện: kiểm tra null trước khi gọi hàm:

a = b && b.length;

Đây là từ ngắn hơn tương đương với:

a = b ? b.length : null;

Phần tốt nhất là bạn có thể kiểm tra chuỗi tài sản:

a = b && b.c && b.c.length;

1

Tôi thích cách làm việc đơn giản với các danh sách:

var numberName = ["zero", "one", "two", "three", "four"][number];

Và băm:

var numberValue = {"zero":0, "one":1, "two":2, "three":3, "four":4}[numberName];

Trong hầu hết các ngôn ngữ khác, đây sẽ là mã khá nặng. Giá trị mặc định cũng rất đáng yêu. Ví dụ báo cáo mã lỗi:

var errorDesc = {301: "Moved Permanently",
                 404: "Resource not found",
                 503: "Server down"
                }[errorNo] || "An unknown error has occurred";

Trông thật tuyệt, tên kỹ thuật của cái này là gì?
TrySpace

0

int sang chuỗi đúc

var i = 12;
var s = i+"";

3
Điều này đối với tôi không có vẻ "ngọt ngào" hơn so với việc thực hiện thẳng i.toString () hoặc String (i). Ngắn! = Đường.
Ates Goral

0
element.innerHTML = "";  // Replaces body of HTML element with an empty string.

Một phím tắt để xóa tất cả các nút con của phần tử.


6
Đó không thực sự là Javascript, đó là DOM và hiện tại nó không chuẩn.
eyelidlessness

0

Chuyển chuỗi thành số nguyên mặc định thành 0 nếu không thể chấp nhận được,

0 | "3" //result = 3
0 | "some string" -> //result = 0
0 | "0" -> 0 //result = 0

Có thể hữu ích trong một số trường hợp, chủ yếu là khi số 0 được coi là kết quả xấu


0

Chữ mẫu

var a = 10;
var b = 20;
var text = `${a} + ${b} = ${a+b}`;

sau đó biến văn bản sẽ như bên dưới!

10 + 20 = 30

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.