var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() )
? 'value'
: 'innerHTML'
Tôi đã nhìn thấy nó trong một câu trả lời, và tôi chưa bao giờ nhìn thấy nó trước đây.
Nó có nghĩa là gì?
var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() )
? 'value'
: 'innerHTML'
Tôi đã nhìn thấy nó trong một câu trả lời, và tôi chưa bao giờ nhìn thấy nó trước đây.
Nó có nghĩa là gì?
Câu trả lời:
~
là một toán tử bitwise lật tất cả các bit trong toán hạng của nó.
Ví dụ: nếu số của bạn là 1
, biểu diễn nhị phân của số float của IEEE 754 (cách JavaScript xử lý số) sẽ là ...
0011 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
Vì vậy, ~
chuyển đổi toán hạng của nó thành số nguyên 32 bit (toán tử bitwise trong JavaScript làm điều đó) ...
0000 0000 0000 0000 0000 0000 0000 0001
Nếu đó là một số âm, nó sẽ được lưu trong phần bù 2: đảo ngược tất cả các bit và thêm 1.
... và sau đó lật tất cả các bit của nó ...
1111 1111 1111 1111 1111 1111 1111 1110
Vì vậy, việc sử dụng nó là gì? Khi nào người ta có thể sử dụng nó?
Nó có khá nhiều công dụng. Nếu bạn đang viết những thứ cấp thấp, nó rất tiện dụng. Nếu bạn lập hồ sơ ứng dụng của bạn và tìm thấy một nút cổ chai, nó có thể được thực hiện nhiều hơn bằng cách sử dụng các thủ thuật bitwise (như một công cụ có thể trong một túi lớn hơn nhiều).
Nó cũng là một (nói chung) không rõ ràng lừa để biến indexOf()
's tìm thấy giá trị trả về vào truthy (trong khi thực hiện không tìm thấy như falsy ) và người ta thường sử dụng nó cho tác dụng phụ của nó cắt xén số đến 32 bit (và thả thập phân của nó bằng cách tăng gấp đôi nó, có hiệu quả tương tự như Math.floor()
đối với các số dương).
Tôi nói không rõ ràng vì nó không rõ ràng ngay lập tức nó được sử dụng để làm gì. Nói chung, bạn muốn mã của bạn giao tiếp rõ ràng với những người khác đang đọc nó. Mặc dù sử dụng ~
có thể trông rất tuyệt , nhưng nhìn chung nó quá thông minh. :)
Bây giờ nó cũng ít liên quan hơn khi JavaScript có Array.prototype.includes()
và String.prototype.includes()
. Chúng trả về một giá trị boolean. Nếu (các) nền tảng đích của bạn hỗ trợ nó, bạn nên thích điều này để kiểm tra sự tồn tại của một giá trị trong chuỗi hoặc mảng.
value = value || default
trong JavaScript là một thành ngữ phổ biến và hợp lệ miễn là bạn biết khi nào bạn có thể và không thể sử dụng nó.
v = t ? a : b;
. Tôi thấy rằng rõ ràng hơn nhiều so với var v; if (t} { v = a; } else { v = b; }
thường được chia trên 5+ dòng và cũng rõ ràng hơn var v = b; if (t) { v = a; }
thường là 4+ dòng. Nhưng tôi biết nhiều người không quen thuộc với các ? :
nhà khai thác, những người thích cách thứ hai hoặc thứ ba. Tôi tìm thấy đầu tiên là dễ đọc hơn. Tôi đồng ý với nguyên tắc chung, làm cho mã rõ ràng, không sử dụng hack. Tôi đoán tôi chỉ thấy ~v.indexOf('...')
rất rõ ràng một khi tôi đã học nó.
~
thành ngữ. đó là kỹ thuật phần của ngôn ngữ đặc tả , nhưng nó không phải là quá nhiều phần của ngôn ngữ được sử dụng chung .
Sử dụng nó trước một indexOf()
biểu thức có hiệu quả mang lại cho bạn kết quả trung thực / sai lệch thay vì chỉ số số được trả về trực tiếp.
Nếu giá trị trả về là -1
, sau đó ~-1
là 0
bởi vì -1
là một chuỗi của tất cả 1 bit. Bất kỳ giá trị nào lớn hơn hoặc bằng 0 sẽ cho kết quả khác không. Như vậy
if (~someString.indexOf(something)) {
}
sẽ khiến if
mã chạy khi "cái gì đó" nằm trong "someString". Nếu bạn cố gắng sử dụng .indexOf()
trực tiếp như một boolean, thì điều đó sẽ không hoạt động vì đôi khi nó trả về 0 (khi "một cái gì đó" ở đầu chuỗi).
Tất nhiên, điều này cũng hoạt động:
if (someString.indexOf(something) >= 0) {
}
và nó ít bí ẩn hơn đáng kể.
Đôi khi bạn cũng sẽ thấy điều này:
var i = ~~something;
Sử dụng ~
toán tử hai lần như vậy là một cách nhanh chóng để chuyển đổi một chuỗi thành số nguyên 32 bit. Cái đầu tiên ~
thực hiện chuyển đổi, và cái thứ hai ~
lật lại các bit. Tất nhiên, nếu toán tử được áp dụng cho thứ gì đó không thể chuyển đổi thành số, NaN
kết quả là bạn sẽ nhận được . ( chỉnh sửa - thực sự đó là lần thứ hai ~
được áp dụng đầu tiên, nhưng bạn có ý tưởng.)
~
khi được thực hiện trên số nguyên là bằng -(x + 1)
.
0
tồn tại false
và khác không true
ngày trở lại, ít nhất là với C trong thập niên 70 và có lẽ rất nhiều ngôn ngữ lập trình hệ thống đương đại khác. Nó có thể bắt nguồn từ cách thức hoạt động của phần cứng; rất nhiều CPU thiết lập một bit 0 sau một hoạt động và có một lệnh rẽ nhánh tương ứng để kiểm tra nó.
| 0
, trong trường hợp đó chỉ là một thao tác.
~~
theo cùng một cách.
Các ~
là Bitwise NOT điều hành , ~x
là gần giống như -(x+1)
. Nó là dễ hiểu hơn, loại. Vì thế:
~2; // -(2+1) ==> -3
Hãy xem xét -(x+1)
. -1
có thể thực hiện thao tác đó để sản xuất a 0
.
Nói cách khác, ~
được sử dụng với một phạm vi các giá trị số sẽ chỉ tạo ra giá trị giả (ép buộc false
từ 0
) cho -1
giá trị đầu vào, nếu không, bất kỳ giá trị trung thực nào khác.
Như chúng ta biết, -1
thường được gọi là giá trị sentinel . Nó được sử dụng cho nhiều chức năng trả lại >= 0
giá trị cho sự thành công và -1
cho thất bại trong ngôn ngữ C. Mà cùng một quy tắc về giá trị trả về của indexOf()
JavaScript.
Thông thường kiểm tra sự hiện diện / vắng mặt của một chuỗi con trong một chuỗi khác theo cách này
var a = "Hello Baby";
if (a.indexOf("Ba") >= 0) {
// found it
}
if (a.indexOf("Ba") != -1) {
// found it
}
if (a.indexOf("aB") < 0) {
// not found
}
if (a.indexOf( "aB" ) == -1) {
// not found
}
Tuy nhiên, sẽ dễ dàng hơn để làm điều đó ~
như dưới đây
var a = "Hello Baby";
~a.indexOf("Ba"); // -7 -> truthy
if (~a.indexOf("Ba")) { // true
// found it
}
~a.indexOf("aB"); // 0 -> falsy
!~a.indexOf("aB"); // true
if (!~a.indexOf( "aB" )) { // true
// not found
}
-(x+1)
nếu tôi thấy nó trong một câu lệnh if. Dấu ngã cho tôi biết chính xác những gì nó đang làm để bù đắp cho bản chất dựa trên 0 của Javascript. Ngoài ra, càng ít dấu ngoặc đơn càng tốt cho việc đọc
if (a.indexOf("Ba") > -1) {// found} //true
, mặc dù dài hơn một chút so với các ví dụ dấu ngã, ít hơn đáng kể so với hai ví dụ bạn đã đưa ra và cho các lập trình viên mới có thể var opinion = !~-1 ? 'more' : 'less'
hiểu được.
~indexOf(item)
xuất hiện khá thường xuyên và câu trả lời ở đây rất hay, nhưng có lẽ một số người chỉ cần biết cách sử dụng và "bỏ qua" lý thuyết:
if (~list.indexOf(item)) {
// item in list
} else {
// item *not* in list
}
++
và --
vì họ "khuyến khích sự ~
list.indexOf(item) >= 0
hoặc ... > -1
vì javascript dựa trên zero và không chọn giải quyết vấn đề này ngay từ đầu. Hơn nữa, chỉ cần ý kiến (giống như Airbnb), bất kỳ ai đang làm bất cứ điều gì có ý nghĩa trong javascript đều biết ++
, và trong khi --
ít phổ biến hơn, ý nghĩa có thể được suy ra.
++
và --
trong một thời gian vì các phương pháp nguyên thủy như map
, forEach
v.v. Quan điểm của tôi là về lý do tại sao họ cũng không cân nhắc ~
quá mức khi bất kỳ tiêu chuẩn nào được sử dụng bao gồm các toán tử tăng và giảm. Để cấm một cái gì đó để CIS101 không có ý nghĩa gì.
Đối với những người xem xét sử dụng các trick dấu ngã để tạo ra một truthy giá trị từ một indexOf
kết quả, nó là rõ ràng hơn và có ít phép thuật để thay vì sử dụng các includes
phương pháp trênString
.
'hello world'.includes('hello') //=> true
'hello world'.includes('kittens') //=> false
Lưu ý rằng đây là một phương pháp tiêu chuẩn mới kể từ ES 2015 vì vậy nó sẽ không hoạt động trên các trình duyệt cũ hơn. Trong trường hợp có vấn đề, hãy cân nhắc sử dụng String.prototype.includes polyfill .
Tính năng này cũng có sẵn cho các mảng sử dụng cú pháp tương tự :
['apples', 'oranges', 'cherries'].includes('apples') //=> true
['apples', 'oranges', 'cherries'].includes('unicorns') //=> false
Dưới đây là Array.prototype.inc loại polyfill nếu bạn cần hỗ trợ trình duyệt cũ hơn.