#javascript
#javascript
Вопрос:
Приведенный ниже код:
var x = 600;
x.foo = true;
console.log("value: ",x);
console.log("foo: ",x.foo);
очевидно, что это не сработает, так как JS-числа распакованы. Очевидной альтернативой было бы вставить все ваши числа:
var x = { value: 600, foo: true }
console.log("value: ",x.value);
console.log("foo: ",x.foo);
но предположим, что вы используете этот метод в дорогостоящем числовом приложении. Тогда вы получаете сильное замедление, так как теперь вы создаете объект в штучной упаковке для каждого отдельного числа в вашем алгоритме, что приведет к хаосу в управлении памятью среды выполнения. Однако, если все, что вам нужно, это флаг, более легким вариантом будет что-то вроде:
var x = flag_as_foo(600);
console.log("value: ",extract_value(x));
console.log("foo: ",is_foo(x));
где flag_as_foo, flag_as_not_foo, is_foo and extract_value
можно было бы работать, переворачивая биты числа или, возможно, используя какую-то умную арифметику. Мой вопрос в том, каков наилучший способ реализовать его в JavaScript? Это не очевидно, учитывая, что в JS нет целых чисел и необычный способ обработки чисел.
Пожалуйста, прочитайте вопрос. Я специально прошу побитовое или арифметическое решение для пометки числа.
Комментарии:
1. Я не понизил голос, но; может быть, вам следует привести несколько четких примеров того, чего вы не хотите. «… без использования массивов / объектов» в целом дисквалифицирует довольно фундаментальные функции языка. Любое решение, которое связывает два значения (число и флаг), будет иметь где-то какой-то объект. Использование
new Number
приемлемо или нет?2. @fernozzle — Технически все в JavaScript является расширением Object , но в документации также говорится, что Number является одним из примитивных типов.
3. @fernozzle
2
отличается отnew Number(2)
4. @Viclib Есть ли какая-нибудь функция на каком-нибудь языке, которая позволяет делать то, что вы хотите, без использования объекта (number), о котором я не знаю? Может быть, я упускаю что-то очевидное
5. @Ian Ну, сегодня я кое-что узнал. Но при каких обстоятельствах
(2)
действует иначе, чемNumber(2)
?
Ответ №1:
На самом деле в JavaScript есть логические целые числа, которые используются при использовании определенных операций, таких как побитовые логические значения и сдвиги. Вот набор функций, которые соответствуют вашим критериям, предполагая, что вы работаете только с целочисленными значениями:
function flag_as_foo(n) {
n = n << 1;
return n | 1;
}
function extract_value(n) {
return n >> 1;
}
function is_foo(n) {
return !!(n amp; 1);
}
var x = flag_as_foo(600);
console.log("value: ",extract_value(x));
console.log("foo: ",is_foo(x));
Это резервирует младший значащий бит в качестве флага. Число, конечно, не может использоваться как правильное значение без его прогона extract_value
(как вы указали), поскольку x
здесь используется не как целое число, а как строка битов (первые 31 из которых представляют число, а 32-й — флаг).
Обратите внимание, что максимальное количество используемых числовых битов здесь становится 31, что ограничено логическим оператором ECMAScript ToInt32
.
Комментарии:
1. Интересно, вы получили вопрос. Могу ли я по-прежнему использовать числа как числа с плавающей запятой?
Ответ №2:
Это самое близкое, что вы можете получить:
var a = new Number(1), b = new Number(2);
a.isBlue = true; //you can do this since a and b are now an Object
console.log(a b); //3
console.log(a.isBlue); //true
Одним из основных недостатков является то, что вам нужно приложить дополнительные усилия, чтобы проверить, совпадают ли два числа:
a == b //false (assuming both have the same value)
Поскольку теперь они являются объектами, вам придется сделать это:
a.valueOf() === b.valueOf() //true
Обновить:
Если вы используете побитовое или арифметическое решение для пометки числа, я бы использовал знак числа (при условии, что у вас есть только возможные числа.) В противном случае я не могу придумать ни одного простого решения.
Ответ №3:
учитывая, что в JS нет целых чисел
Для начала вы не можете хранить какой-либо флаг в int. Тем не менее, лучшим вариантом было бы использовать объектный литерал. Я понимаю, что вы указали в своем вопросе, что не хотели использовать объекты. Тем не менее, делая что-то вроде
var a = {"number": "1337" , "color": "blue"};
alert(a.color);
кажется, это имеет наибольший смысл.
Комментарии:
1. Это невозможно, когда вы используете эти числа в дорогостоящем приложении. Т. Е. это невыносимо медленно.
2. Я понимаю. Теперь с вашим более подробным вопросом я понимаю. Спасибо