a

Câu hỏi Kiểm tra xem một biến là một chuỗi trong JavaScript


Làm thế nào tôi có thể xác định xem một biến là một chuỗi hoặc một cái gì đó khác trong JavaScript?


1178
2017-10-30 14:36


gốc


Nhìn lại bốn năm sau đó là sự khiêm nhường nhưng vẫn rất đáng nể. Có những câu hỏi ngu ngốc, nhưng không sao. Hỏi loại điều này là cách duy nhất tôi sẽ học: D - Olical
@ Kinh Thánh Tôi sẽ không cảm thấy rằng xấu, như của ngày hôm nay, hơn 518 người đã bình chọn cho một câu trả lời mà không phải là thực sự chính xác, so với 851 người tìm thấy một Câu trả lời chính xác. Bạn đã tạo ra những gì có lẽ là định nghĩa kinh điển của xác định xem một biến là một chuỗi trong cộng đồng Javascript. Thật không may là cộng đồng SO cung cấp một câu trả lời tồi tệ như vậy cho câu hỏi tuyệt vời của bạn. :) - Orwellophile
@Orwellophile bây giờ chúng tôi sáu năm. Tôi vẫn sử dụng phương thức kiểm tra kiểu typeof hoặc lodash nếu chúng có sẵn. Tôi không gặp vấn đề gì với câu trả lời được chấp nhận tại bất kỳ thời điểm nào trong sự nghiệp của tôi. Nó có thể không "hoàn hảo" nhưng nó hoạt động :) - Olical
@ Kinh Thánh tôi nhận được câu trả lời của tôi từ gạch dưới (lodash), vì vậy tôi không thể nói cao hơn về lựa chọn đó. Tuy nhiên, kể từ khi bạn đề cập đến sự nghiệp, nếu tôi phỏng vấn bạn, tôi có thể sẽ không nhận thấy nếu bạn sử dụng typeof, nhưng tôi sẽ thông báo (và được ấn tượng phù hợp) nếu bạn sử dụng toString.call(x) === "[object String]" - Orwellophile
Tôi đã làm điều này trong nhiều năm, và tôi vẫn quên: / - Captain Hypertext


Các câu trả lời:


Bạn có thể dùng typeof nhà điều hành:

var booleanValue = true; 
var numericalValue = 354;
var stringValue = "This is a String";
alert(typeof booleanValue) // displays "boolean"
alert(typeof numericalValue) // displays "number"
alert(typeof stringValue) // displays "string"

Ví dụ từ trang web này. (Ví dụ đã được sửa đổi chút ít).


1103
2017-10-30 14:40



@ Wolfy87 Xin lưu ý rằng có một số trường hợp typeof stringValue có thể trả về "đối tượng" thay vì "chuỗi". Xem nhận xét về câu trả lời của tôi. - DRAX
Câu trả lời ưa thích của tôi. Các đối số chống lại nó là nó 'không' cho các chuỗi bọc đối tượng như new String('foo'), nhưng điều đó không quan trọng bởi vì chuỗi bọc đối tượng là một tính năng vô giá trị mà bạn không nên sử dụng. Hướng dẫn kiểu Google cấm họ, Douglas Crockford muốn họ không dùng nữavà không có thư viện nào sử dụng chúng. Giả sử họ không tồn tại và sử dụng typeof không sợ hãi. - Mark Amery
Không Douglas Crockford khuyên rằng typeof không được chấp nhận cũng? - Daniel Le
@DanielLe, bởi vì anh ta đã đề xuất một sự thay thế để sửa một số vấn đề, không phải vì anh ta chống lại nó về nguyên tắc. - Vsevolod Golovanov
@VsevolodGolovanov Làm thế nào để bạn biết rằng anh ta không chống lại nó về nguyên tắc? Tất cả những gì tôi biết là những vấn đề đó chính xác là lý do tại sao anh ấy khuyên rằng việc thực hiện hiện tại typeof không được chấp nhận. - Daniel Le


Đây là những gì làm việc cho tôi:

if (typeof myVar === 'string' || myVar instanceof String)
// it's a string
else
// it's something else

1462
2018-02-24 19:38



"MyVar instanceof String" có làm bất cứ điều gì ở trên và ngoài "typeof myVar == 'string'" không? - svth
@svth tôi nhớ. Trong JavaScript, bạn có thể có loại biến của chuỗi hoặc loại đối tượng là lớp String (cùng một điều - cả hai đều là chuỗi - nhưng được định nghĩa khác nhau) đó là lý do tại sao được kiểm tra lại. - DRAX
var somevar = new String ('somestring') console.log (typeof somevar) // đối tượng - Danubian Sailor
-1 vì instanceof kiểm tra ở đây là tiếng ồn vô nghĩa trừ khi bạn đang theo dõi một số rất khác thường thực hành mã hóa, và câu trả lời này không có gì để giải thích những gì nó làm hoặc tại sao bạn có thể sử dụng nó. Lý do duy nhất bạn cần nó là nếu bạn sử dụng các chuỗi bọc đối tượng, nhưng các chuỗi bọc đối tượng là một tính năng vô giá trị mà không ai sử dụng và Google và Crockford đều coi đó là hành vi xấu (google-styleguide.googlecode.com/svn/trunk/…, crockford.com/javascript/recommend.html). - Mark Amery
Tôi vất vả không đồng ý rằng việc viết mã vững chắc để xử lý chính xác các trường hợp không chắc chắn là điều cần tránh. Kiểm tra cả hai typeof và instanceof cảm thấy như lời khuyên tốt nếu mã của bạn có thể được gọi bởi người khác '. @ MarkAmery's postmessage trường hợp cạnh có vấn đề nếu bạn hỏi "tôi chỉ là cái gì postmessaged? "- nhưng bạn mong muốn được xử lý tại giao diện và không được phép truyền bá. Ở những nơi khác, có vẻ như chính xác để xử lý các phương thức mã hóa không được chấp nhận ngay cả khi một số thẩm mỹ JS không chấp nhận chúng. , trừ khi nó thực sự! - Dewi Morgan


Kể từ 580+ người đã bỏ phiếu cho một câu trả lời không chính xác, và hơn 800 người đã bỏ phiếu cho một câu trả lời làm việc nhưng theo kiểu súng ngắn, tôi nghĩ có thể sẽ làm giảm câu trả lời của tôi theo một dạng đơn giản mà mọi người đều có thể hiểu được.

function isString(x) {
  return Object.prototype.toString.call(x) === "[object String]"
}

Hoặc, nội tuyến (Tôi có một thiết lập UltiSnip cho việc này):

Object.prototype.toString.call(myVar) === "[object String]"

FYI, câu trả lời của Pablo Santa Cruz là sai, bởi vì typeof new String("string") Là object

Câu trả lời của DRAX là chính xác và có chức năng, và phải là câu trả lời đúng (vì Pablo Santa Cruz chắc chắn là không chính xác, và tôi sẽ không tranh cãi với cuộc bỏ phiếu phổ biến.)

Tuy nhiên, câu trả lời này cũng chắc chắn là đúng, và thực sự là câu trả lời hay nhất (ngoại trừ, có lẽ, với đề nghị sử dụng lodash/gạch dưới). tuyên bố từ chối trách nhiệm: Tôi đã đóng góp cho codebase lodash 4.

Câu trả lời ban đầu của tôi (mà rõ ràng đã bay ngay trên rất nhiều đầu) như sau:

Tôi đã chuyển mã này từ underscore.js:

['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'].forEach( 
    function(name) { 
        window['is' + name] = function(obj) {
              return toString.call(obj) == '[object ' + name + ']';
    }; 
});

Điều đó sẽ định nghĩa isString, isNumber, v.v.


Trong Node.js, điều này có thể được thực hiện như một module:

module.exports = [
  'Arguments', 
  'Function', 
  'String', 
  'Number', 
  'Date', 
  'RegExp'
].reduce( (obj, name) => {
  obj[ 'is' + name ] = x => toString.call(x) == '[object ' + name + ']';
  return obj;
}, {});

101
2017-07-21 11:59



Bạn đề nghị underscore.js (vì lý do kỳ quặc nào?) Nhưng bạn không sử dụng nó ở đây. Hơn nữa bạn gây ô nhiễm không gian tên chung với các hàm. Trong node.js bạn sẽ tạo một mô-đun có tất cả các chức năng này (bạn có thể sử dụng global || window thay vì window nhưng đó sẽ là một cách tiếp cận xấu để giải quyết một vấn đề bạn không nên có ở nơi đầu tiên). - Benjamin Gruenbaum
@BenjaminGruenbaum Tôi đã tìm câu trả lời cho câu hỏi của OP, và không thích bất kỳ câu trả lời nào. Vì vậy, tôi đã kiểm tra những gì gạch dưới đã làm, và nghĩ rằng nó là tiện lợi, đủ để trích xuất và sửa đổi một chút (để tránh phải có thư viện gạch dưới tải). Tôi sẽ làm rõ bài đăng của mình. - Orwellophile
@Orwellophile Cool, tôi nhận được nó ngay bây giờ, câu trả lời ban đầu của bạn đã được phrased như bạn đang đề nghị gạch dưới chính nó. Cá nhân tôi chỉ cần kiểm tra myObject+"" === myObject để kiểm tra nếu một đối tượng là một chuỗi (hoặc thậm chí tốt hơn, tôi sẽ không gõ kiểm tra trong một hệ thống loại hành vi điều khiển ở nơi đầu tiên). - Benjamin Gruenbaum
Giải pháp tuyệt vời cho những người có mối quan tâm về kiến ​​trúc hệ thống. - Ihsan
@Orwellophile, Điều này tốt hơn câu trả lời của DRAX như thế nào? - Pacerier


Tôi khuyên bạn nên sử dụng các hàm tích hợp từ jQuery hoặc là lodash / Underscore. Chúng dễ sử dụng hơn và dễ đọc hơn.

Một trong hai hàm sẽ xử lý trường hợp DRAX được đề cập ... nghĩa là, chúng cả hai kiểm tra xem (A) biến là một chuỗi ký tự hay (B) là một thể hiện của đối tượng String. Trong cả hai trường hợp, các hàm này xác định chính xác giá trị dưới dạng chuỗi.

lodash / Underscore.js

if(_.isString(myVar))
   //it's a string
else
   //it's something else

jQuery

if($.type(myVar) === "string")
   //it's a string
else
   //it's something else

Xem lodash Tài liệu cho _.isString () để biết thêm chi tiết.

Xem Tài liệu jQuery cho $ .type () để biết thêm chi tiết.


78
2018-01-06 20:43



Đây là điều cần thiết của những gì là sai với cộng đồng JS - kiểm tra chống lại kiểu nguyên thủy là một lớp lót và chỉ liên quan đến xây dựng ngôn ngữ (một trong những cơ bản), nhưng bạn khuyên bạn nên sử dụng thư viện bên ngoài. Nếu ai đó đã sử dụng một trong các thư viện này thì đó có thể là một ý tưởng hay, nhưng việc tải chúng xuống chỉ vì điều đó thay vì chỉ đơn giản là kiểm tra kiểu là quá mức cần thiết. - Rafał Wrzeszcz
Tôi sẽ đồng ý với Rafal. Tôi thấy ở khắp mọi nơi rằng nó cải thiện "khả năng đọc" để sử dụng một trong các thư viện bên ngoài này. Nếu bạn biết JavaScript, thì đó là dễ đọc hơn một số thư viện bên ngoài mà bạn chưa sử dụng. _.every() có một chút khó hiểu khi sử dụng lúc đầu và điều gì đó đơn giản như _.isBoolean() đã nhầm lẫn devs tại công ty của tôi. Một dev sai lầm nghĩ rằng nó sẽ là sai nếu giá trị là một boolean và là sai. Tiếng Anh dễ đọc hơn tiếng Đức đối với tôi, bởi vì tôi không biết tiếng Đức. Tìm hiểu JavaScript và tất cả sẽ có ý nghĩa. - John Harding
@ RafałWrzeszcz Các thư viện này được sử dụng khá rộng rãi và cung cấp nhiều chức năng (và thử nghiệm) hữu ích. Đặc biệt là lodash. Tôi sẽ không đề nghị ai đó tải thư viện xuống chỉ để sử dụng cho giải pháp này .... nhưng tôi sẽ khuyên mọi nhà phát triển javascript tải xuống thư viện này và xem họ đang bỏ lỡ điều gì. ;) - ClearCloud8
Tất cả các bạn đều thiếu điểm của một thư viện như Lodash: không phải tốc độ. Không phải "dễ phát triển". Nguyên nhân để sử dụng một thư viện như Lodash cung cấp "defensiveness" đối với các vấn đề sẽ làm nổ tung ứng dụng js của bạn. Lỗi nghiêm trọng xảy ra khi bạn cố gắng thực hiện các hoạt động chuỗi trên một đối tượng (hoặc ngược lại), và Lodash cung cấp giá trị to lớn xung quanh ngăn chặn các lỗi đó. - cale_b
Ghi nhớ rằng nhiều người sẽ làm điều này trong môi trường Node hoặc Node, và rất ít người sẽ sử dụng jQuery ở đó. - Matt Fletcher


function isString (obj) {
  return (Object.prototype.toString.call(obj) === '[object String]');
}

Tôi thấy rằng ở đây:

http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/


28
2017-07-24 19:07



Tôi nghĩ rằng giải pháp này là mạnh nhất vì nó xử lý các kịch bản tham chiếu chéo / khung cửa sổ như được đề cập trong URL được cung cấp trong câu trả lời. - ewh
Câu trả lời hay, có vẻ như Underscore.js cũng sử dụng phương pháp này! - Daan
@ling Chỉ tò mò, tại sao bạn đặt ngoặc đơn xung quanh Object.prototype.toString.call(obj) === '[object String]'? - StubbornShowaGuy
@StubbornShowaGuy, tôi đoán đó là khả năng đọc mã. - Earlee
@Earlee Bạn có nghĩa là (x === y) có khả năng đọc tốt hơn x === y? - StubbornShowaGuy


Bạn có thể sử dụng lại nguồn mở này thành phần chuỗi để kiểm tra xem var có phải là chuỗi không trong khi tránh sao chép.

Ví dụ:

 isString(3) // => false
 isString('') // => true

Ngoài ra, đây là cách isString đã được triển khai trong AngularJS:

function isString(value) {return typeof value === 'string';}

23
2018-02-10 13:10



Làm thế nào để cải thiện câu trả lời của DRAX? - Sheljohn


Cách tốt nhất:

var s = 'String';
var a = [1,2,3];
var o = {key: 'val'};

(s.constructor === String) && console.log('its a string');
(a.constructor === Array) && console.log('its an array');
(o.constructor === Object) && console.log('its an object');
(o.constructor === Number || s.constructor === Boolean) && console.log('this won\'t run');

Mỗi trong số này đã được xây dựng bởi hàm lớp thích hợp của nó, như "đối tượng mới ()", v.v.

Ngoài ra, nhập vai vịt: "Nếu nó trông giống như một con vịt, đi như một con vịt, và có mùi giống như một con vịt - nó phải là một Array" Có nghĩa là, kiểm tra các thuộc tính của nó.

Hi vọng điêu nay co ich.

Chỉnh sửa; 12/05/2016

Hãy nhớ rằng, bạn luôn có thể sử dụng kết hợp các phương pháp tiếp cận quá. Dưới đây là ví dụ về cách sử dụng bản đồ nội tuyến hành động với loại:

var type = { 'number': Math.sqrt.bind(Math), ... }[ typeof datum ];

Dưới đây là ví dụ 'thế giới thực' hơn về việc sử dụng bản đồ nội tuyến:

function is(datum) {
    var isnt = !{ null: true, undefined: true, '': true, false: false, 0: false }[ datum ];
    return !isnt;
}
console.log( is(0), is(false), is(undefined), ... );  // >> true true false

Hàm này sẽ sử dụng "kiểu" đúc "- thay vào đó," gõ - / - giá trị ánh xạ "- để tìm ra nếu một biến thực sự" tồn tại ". Bây giờ bạn có thể chia tóc khó chịu giữa null& 0!

Nhiều lần bạn thậm chí không quan tâm đến loại của nó. Một cách khác để phá vỡ đánh máy là kết hợp các bộ Duck-Type:

this.id = "998";  // use a number or a string-equivalent
function get(id) {
    if (!id || !id.toString) return;
    if (id.toString() === this.id.toString()) http( id || +this.id );
    // if (+id === +this.id) ...;
}

Cả hai Number.prototype    String.prototype có một .toString() method. Bạn chỉ cần đảm bảo rằng chuỗi tương đương với số này giống nhau, và sau đó bạn chắc chắn rằng bạn đã chuyển nó vào http hoạt động như một Number. Nói cách khác, chúng tôi thậm chí không quan tâm loại của nó là gì.

Hy vọng rằng cung cấp cho bạn nhiều hơn để làm việc với :)


15
2018-04-25 13:15



Bạn sẽ cần một số kiểm tra khác cho các số cũ đơn giản, vì cố gắng lấy thuộc tính hàm tạo của chúng sẽ thất bại:
@torazaburo Đã làm việc tốt cho tôi ngay bây giờ trong bảng điều khiển Chrome. Điều gì khiến bạn nghĩ rằng nó sẽ không hoạt động? - Mark Amery
@torazaburo Bạn có thể muốn chơi với các xác nhận ( (o.constructor === Number || s.constructor === Boolean) ). Anecdotally, parseInt và NaN là những công cụ mỏng manh nhưng mạnh mẽ. Chỉ cần nhớ, Not-a-Number là NOT-a-Number, và undefined có thể được định nghĩa. - Cody
a.constructor === Mảng là sai và đôi khi có thể thất bại, sử dụng Array.isArray xem web.mit.edu/jwalden/www/isArray.html - axkibe
Đồng ý, điều này không an toàn. Một cách tốt hơn là sử dụng kiểm tra tài sản - Đó là cách duy nhất thực sự không an toàn tại thời điểm này. Thí dụ: if(thing.call) { 'its a function'; } hoặc là if(thing.defineProperties) { 'its an object'; }. Cảm ơn cho đầu vào, axkibe! - Cody


Lấy từ lodash:

function isString(val) {
   return typeof val === 'string' || ((!!val && typeof val === 'object') && Object.prototype.toString.call(val) === '[object String]');
}

console.log(isString('hello world!')); // true
console.log(isString(new String('hello world'))); // true

7
2017-09-06 05:06