2014-09-30 5 views
36

Почему значение data-value="2.0" относится к строкам, а значение data-value="2.5" относится к числу? Я могу справиться с этим штрафом в рамках моей функции. Я просто пытаюсь понять немного больше о том, как Javascript обрабатывает номера и строки. Этот вид заставил меня остерегаться.HTML5 data- * type type casting strings and numbers

<a data-value="2.0">2.0</a> 
<a data-value="2.5">2.5</a> 
$("a").click(function() { 
    alert(typeof $(this).data("value")); 
}); 

[ Fiddle With It ]

+0

Я не знаю, почему это происходит, но вы можете видеть, что поплавки заканчивающееся на '0' являются всегда притворялись струнами. Может быть, потому, что последний '0' не имеет значения и интерпретируется как текст. Например: '2.5' - это номер, а' 2.50' - строка. – TheFrozenOne

+13

Метод '.data' jQuery будет пытаться преобразовать все, что находится в атрибуте' data- * ', - если вы хотите, чтобы оно было как строковое значение строки, используйте' .attr («data - *») ' – tymeJV

+0

@tymeJV спасибо за Берегись! – Matt

ответ

28

Эти значения являются просто строки ванили Javascript; он не пытается конвертировать самостоятельно.

[...document.querySelectorAll("a")].forEach(a => 
 
    console.log("type: %s, value: %o", 
 
       typeof a.dataset.value, 
 
       a.dataset.value) 
 
);
<a data-value="2.0">2.0</a> 
 
<a data-value="2.5">2.5</a>

JQuery, с другой стороны, пытается определить и преобразовать в соответствующий тип при доступе к данным атрибутов с помощью data(). Это (возможно) проблема с их реализацией. Их documentation (курсив мой) фактически решает эту проблему:

Каждая попытка преобразовать строку в значение JavaScript (это включает в себя булевы, числа, объекты, массивы и нуль). Значение преобразуется только в число, если это не изменяет представление значения. Например, «1E02» и «100.000» эквивалентны цифрам (числовое значение 100), но их преобразование изменит их представление, чтобы они оставались в виде строк. значение строки «100» преобразуется в количестве 100.

Смотрите также HTMLElement. dataset

+1

Спасибо! Я не понимал, что JQuery сделал это. Я потратил часы, объединившись с 600-строчным скриптом, который искал ошибку, и теперь чувствую себя очень глупо! +1 Для примера. – Matt

+1

Полезно знать об этом изменении. Оказывается, так было с 1.8 rc 1. – zzzzBov

1

Это, кажется, что лечение».0" расширение числа как строки.

Если все значения данных будут приходить в в таком формате, просто выскочить в parseFloat() на этих сосунков, как это:

$("a").click(function() { 
    alert(typeof parseFloat($(this).data("value"))); 
}); 

Таким образом, это не имеет значения, если они являются строками или числами , они всегда будут рассматриваться как числа (целые десятичные числа).

+2

Не будет ['parseFloat()'] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseFloat) более уместным с учетом '2.5'? – canon

+0

@canon абсолютно прав –

1

Как упоминалось в tymeJV, это выглядит как проблема с тем, как jquery обрабатывает автоконверсию. Если вы используете «2», он также дает номер, поэтому я предполагаю, что он просто странный крайний случай в том, как они обрабатывают вещи. Я бы посоветовал просто использовать .attr ('xxx') и разобрать ваши данные на свой известный тип.

0

Я думаю, что это больше вопрос о том, как jquery идентифицирует числа. Если вы используете alert(typeof(this.getAttribute("data-value")));, он выспит, что это строка как раз (что ожидается). Насколько я знаю, все в атрибуте html считается строкой, только разные библиотеки могут иметь поведение по умолчанию, которое интерпретирует их по-разному.

Кроме того, сокращенный способ, чтобы получить число было бы что-то вдоль линий ...

var someNumber = +$(someElt).data("value"); 

+ будет вызывать тип принуждение, если возвращаемое значение является строкой, или оставить его в покое, если это уже номер.

4

По умолчанию все, что анализируется атрибутом, будет строкой, вам нужно будет преобразовать его в число, если вам нужно использовать его как число. Лучший способ я был в состоянии справиться с этим, окружив его с помощью функции Number (родной Javascript)

var number = Number($(this).data("value")); 
ParseInt будет возвращать целое число (целое число), так что если вы хотите сохранить ваши десятичные значения вам нужно будет использовать Number. Осторожно с parseInt, всегда лучше указать базу, если вы хотите разобрать int, parseInt ($ (this) .data ("value"), 10);
+0

Зачем ему вообще 'parseInt()'? Он имеет десятичные значения, такие как '2.5'. – canon

+0

Я отправил свой ответ после @dave lunny, который ранее ссылался на parseInt, но с тех пор редактировал его. Я должен был быть более явным. Я удалю по этой части, чтобы избежать путаницы. – zmehboob

20

Просмотрев исходный код jQuery, я определил причину.

Он будет анализировать его как число, если и только если, то это не изменит строку. Источник: https://github.com/jquery/jquery/blob/master/src/data.js#L36

(+"2.0") + "" === "2" // !== the original string 
(+"2.1") + "" === "2.1" // == the original string