JavaScript Number对象
Number 对象是 JavaScript 中表示数字的基本对象。它不仅包含基本的数值类型,还提供了许多有用的属性和方法来处理数字。在本章节中,我们将深入学习 JavaScript 中的 Number 对象及其各种特性和方法。
什么是 Number 对象
在 JavaScript 中,数字是一种基本数据类型,但同时也存在 Number 对象。Number 对象提供了处理数字的各种属性和方法。
Number 的特点
- 基本类型:JavaScript 中的数字是基本类型
- 对象包装:Number 对象是数字的包装对象
- 自动转换:基本数字类型会自动转换为 Number 对象
- 精度限制:遵循 IEEE 754 标准的双精度浮点数
Number 基本用法
创建 Number
javascript
// 字面量方式(推荐)
const num1 = 42;
const num2 = 3.14;
const num3 = -10;
// Number 构造函数
const num4 = new Number(42);
const num5 = new Number("3.14");
const num6 = new Number(true); // 1
const num7 = new Number(false); // 0
const num8 = new Number(null); // 0
const num9 = new Number(undefined); // NaN
console.log(typeof num1); // "number"
console.log(typeof num4); // "object"
console.log(num1 === num4); // false (类型不同)
console.log(num1 == num4); // true (值相同)
// Number 函数(类型转换)
const num10 = Number("42");
const num11 = Number("3.14");
const num12 = Number(true);
const num13 = Number(false);
const num14 = Number("hello"); // NaN
console.log(num10); // 42
console.log(num11); // 3.14
console.log(num12); // 1
console.log(num13); // 0
console.log(num14); // NaN数字字面量
javascript
// 整数字面量
const decimal = 42; // 十进制
const binary = 0b101010; // 二进制 (ES6)
const octal = 0o52; // 八进制 (ES6)
const hex = 0x2A; // 十六进制
console.log(decimal); // 42
console.log(binary); // 42
console.log(octal); // 42
console.log(hex); // 42
// 浮点数字面量
const float1 = 3.14;
const float2 = .5; // 0.5
const float3 = 5.; // 5.0
const scientific1 = 1e5; // 100000
const scientific2 = 1.5e-2; // 0.015
console.log(float1); // 3.14
console.log(float2); // 0.5
console.log(float3); // 5
console.log(scientific1); // 100000
console.log(scientific2); // 0.015
// BigInt (ES2020)
const bigInt = 123456789012345678901234567890n;
console.log(bigInt); // 123456789012345678901234567890nNumber 静态属性
javascript
// 基本数学常量
console.log(Number.EPSILON); // 2.220446049250313e-16 (最小差值)
console.log(Number.MAX_VALUE); // 1.7976931348623157e+308 (最大值)
console.log(Number.MIN_VALUE); // 5e-324 (最小正值)
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991 (最大安全整数)
console.log(Number.MIN_SAFE_INTEGER); // -9007199254740991 (最小安全整数)
console.log(Number.POSITIVE_INFINITY); // Infinity
console.log(Number.NEGATIVE_INFINITY); // -Infinity
console.log(Number.NaN); // NaN
// 检查特殊值
console.log(1 / 0); // Infinity
console.log(-1 / 0); // -Infinity
console.log(0 / 0); // NaN
console.log(Math.sqrt(-1)); // NaN
// 检查是否为有限数
console.log(Number.isFinite(42)); // true
console.log(Number.isFinite(Infinity)); // false
console.log(Number.isFinite(-Infinity)); // false
console.log(Number.isFinite(NaN)); // false
console.log(Number.isFinite("42")); // false (不会类型转换)
// 对比全局 isFinite
console.log(isFinite("42")); // true (会类型转换)
console.log(isFinite(42)); // trueNumber 静态方法
类型检查方法
javascript
// Number.isNaN() - 检查是否为 NaN
console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN(42)); // false
console.log(Number.isNaN("hello")); // false
console.log(Number.isNaN("NaN")); // false
// 对比全局 isNaN
console.log(isNaN(NaN)); // true
console.log(isNaN("hello")); // true (会类型转换)
console.log(isNaN("NaN")); // true
// Number.isInteger() - 检查是否为整数
console.log(Number.isInteger(42)); // true
console.log(Number.isInteger(42.0)); // true
console.log(Number.isInteger(42.1)); // false
console.log(Number.isInteger("42")); // false
console.log(Number.isInteger(Infinity)); // false
// Number.isSafeInteger() - 检查是否为安全整数
console.log(Number.isSafeInteger(42)); // true
console.log(Number.isSafeInteger(9007199254740991)); // true
console.log(Number.isSafeInteger(9007199254740992)); // false
console.log(Number.isSafeInteger(1.5)); // false类型转换方法
javascript
// Number.parseInt() - 解析整数
console.log(Number.parseInt("42")); // 42
console.log(Number.parseInt("42.5")); // 42
console.log(Number.parseInt("42px")); // 42
console.log(Number.parseInt("px42")); // NaN
console.log(Number.parseInt("FF", 16)); // 255
// 与全局 parseInt 的区别
console.log(parseInt("42")); // 42
console.log(Number.parseInt === parseInt); // true
// Number.parseFloat() - 解析浮点数
console.log(Number.parseFloat("3.14")); // 3.14
console.log(Number.parseFloat("3.14px")); // 3.14
console.log(Number.parseFloat("px3.14")); // NaN
// 与全局 parseFloat 的区别
console.log(parseFloat("3.14")); // 3.14
console.log(Number.parseFloat === parseFloat); // trueNumber 实例方法
数值格式化
javascript
const num = 1234.5678;
// toFixed() - 固定小数位数
console.log(num.toFixed(2)); // "1234.57"
console.log(num.toFixed(0)); // "1235"
console.log(num.toFixed(6)); // "1234.567800"
console.log((1.235).toFixed(2)); // "1.24" (四舍五入)
// toExponential() - 指数表示法
console.log(num.toExponential()); // "1.2345678e+3"
console.log(num.toExponential(2)); // "1.23e+3"
console.log(num.toExponential(6)); // "1.234568e+3"
// toPrecision() - 指定有效数字
console.log(num.toPrecision()); // "1234.5678"
console.log(num.toPrecision(6)); // "1234.57"
console.log(num.toPrecision(3)); // "1.23e+3"
// toString() - 转换为字符串
console.log(num.toString()); // "1234.5678"
console.log(num.toString(16)); // "4d2.9197979797979"
console.log(num.toString(2)); // "10011010010.10010001100101111000110111101011100001010001111011"
console.log(num.toString(8)); // "2322.4431573332342"数值检查
javascript
const num = 42;
// valueOf() - 返回原始值
console.log(num.valueOf()); // 42
console.log(typeof num.valueOf()); // "number"
// toLocaleString() - 本地化字符串表示
console.log(num.toLocaleString()); // "42"
console.log((1234567.89).toLocaleString("zh-CN")); // "1,234,567.89"
console.log((1234567.89).toLocaleString("de-DE")); // "1.234.567,89"
// 使用选项
console.log((1234567.89).toLocaleString("zh-CN", {
style: "currency",
currency: "CNY"
})); // "¥1,234,567.89"
console.log((0.1).toLocaleString("zh-CN", {
style: "percent"
})); // "10%"数字运算和精度问题
浮点数精度问题
javascript
// 浮点数精度问题
console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // false
// 解决方案1:使用 toFixed()
console.log((0.1 + 0.2).toFixed(1)); // "0.3"
console.log(parseFloat((0.1 + 0.2).toFixed(10))); // 0.3
// 解决方案2:使用整数运算
function add(a, b) {
const factor = 10;
return (a * factor + b * factor) / factor;
}
console.log(add(0.1, 0.2)); // 0.3
// 解决方案3:使用 Number.EPSILON
function isEqual(a, b) {
return Math.abs(a - b) < Number.EPSILON;
}
console.log(isEqual(0.1 + 0.2, 0.3)); // true
// 解决方案4:自定义精度比较
function isEqualWithPrecision(a, b, precision = 10) {
return Math.abs(a - b) < Math.pow(10, -precision);
}
console.log(isEqualWithPrecision(0.1 + 0.2, 0.3, 10)); // true大数运算
javascript
// 超出安全整数范围的问题
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
console.log(Number.MAX_SAFE_INTEGER + 1); // 9007199254740992
console.log(Number.MAX_SAFE_INTEGER + 2); // 9007199254740992 (精度丢失)
// 使用 BigInt (ES2020)
const bigNum1 = 9007199254740991n;
const bigNum2 = 9007199254740992n;
const bigNum3 = 9007199254740993n;
console.log(bigNum1 + 1n); // 9007199254740992n
console.log(bigNum2 + 1n); // 9007199254740993n
console.log(bigNum3 + 1n); // 9007199254740994n
// BigInt 运算
console.log(123456789012345678901234567890n * 2n); // 246913578024691357802469135780n
console.log(2n ** 100n); // 1267650600228229401496703205376n
// BigInt 与 Number 的转换
const bigInt = 42n;
const num = 42;
// BigInt 转 Number
console.log(Number(bigInt)); // 42
// Number 转 BigInt (需要是整数)
console.log(BigInt(num)); // 42n
// console.log(BigInt(3.14)); // RangeErrorNumber 工具函数
数值验证
javascript
class NumberUtils {
// 检查是否为数字
static isNumber(value) {
return typeof value === "number" && !isNaN(value);
}
// 检查是否为整数
static isInteger(value) {
return Number.isInteger(value);
}
// 检查是否为安全整数
static isSafeInteger(value) {
return Number.isSafeInteger(value);
}
// 检查是否为有限数
static isFinite(value) {
return Number.isFinite(value);
}
// 检查是否为 NaN
static isNaN(value) {
return Number.isNaN(value);
}
// 解析整数
static parseInt(value, radix = 10) {
return Number.parseInt(value, radix);
}
// 解析浮点数
static parseFloat(value) {
return Number.parseFloat(value);
}
// 安全的数字比较
static isEqual(a, b, epsilon = Number.EPSILON) {
return Math.abs(a - b) < epsilon;
}
// 检查是否在范围内
static inRange(value, min, max) {
return value >= min && value <= max;
}
// 限制数值范围
static clamp(value, min, max) {
return Math.min(Math.max(value, min), max);
}
// 四舍五入到指定小数位
static round(value, decimals = 0) {
const factor = Math.pow(10, decimals);
return Math.round(value * factor) / factor;
}
// 向下取整到指定小数位
static floor(value, decimals = 0) {
const factor = Math.pow(10, decimals);
return Math.floor(value * factor) / factor;
}
// 向上取整到指定小数位
static ceil(value, decimals = 0) {
const factor = Math.pow(10, decimals);
return Math.ceil(value * factor) / factor;
}
// 格式化数字
static format(value, options = {}) {
const {
decimals = 2,
thousandSeparator = ",",
decimalSeparator = "."
} = options;
const fixed = value.toFixed(decimals);
const [integer, decimal] = fixed.split(".");
const formattedInteger = integer.replace(
/\B(?=(\d{3})+(?!\d))/g,
thousandSeparator
);
return decimal
? formattedInteger + decimalSeparator + decimal
: formattedInteger;
}
// 生成随机数
static random(min = 0, max = 1) {
return Math.random() * (max - min) + min;
}
// 生成随机整数
static randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// 检查是否为质数
static isPrime(num) {
if (num <= 1) return false;
if (num <= 3) return true;
if (num % 2 === 0 || num % 3 === 0) return false;
for (let i = 5; i * i <= num; i += 6) {
if (num % i === 0 || num % (i + 2) === 0) {
return false;
}
}
return true;
}
// 获取数字的位数
static getDigitCount(num) {
return Math.abs(num).toString().length;
}
// 反转数字
static reverse(num) {
return parseFloat(
num
.toString()
.split("")
.reverse()
.join("")
) * Math.sign(num);
}
}
// 使用示例
console.log(NumberUtils.isNumber(42)); // true
console.log(NumberUtils.isInteger(42.0)); // true
console.log(NumberUtils.isSafeInteger(9007199254740991)); // true
console.log(NumberUtils.isFinite(42)); // true
console.log(NumberUtils.isNaN(NaN)); // true
console.log(NumberUtils.parseInt("42px")); // 42
console.log(NumberUtils.parseFloat("3.14px")); // 3.14
console.log(NumberUtils.isEqual(0.1 + 0.2, 0.3)); // true
console.log(NumberUtils.inRange(5, 1, 10)); // true
console.log(NumberUtils.clamp(15, 1, 10)); // 10
console.log(NumberUtils.round(3.14159, 2)); // 3.14
console.log(NumberUtils.floor(3.14159, 2)); // 3.14
console.log(NumberUtils.ceil(3.14159, 2)); // 3.15
console.log(NumberUtils.format(1234567.89)); // "1,234,567.89"
console.log(NumberUtils.format(1234567.89, {
decimals: 0,
thousandSeparator: " ",
decimalSeparator: ","
})); // "1 234 568"
console.log(NumberUtils.random(1, 10)); // 1到10之间的随机数
console.log(NumberUtils.randomInt(1, 10)); // 1到10之间的随机整数
console.log(NumberUtils.isPrime(17)); // true
console.log(NumberUtils.isPrime(18)); // false
console.log(NumberUtils.getDigitCount(12345)); // 5
console.log(NumberUtils.reverse(12345)); // 54321数字格式化和国际化
Intl.NumberFormat
javascript
// 基本用法
const number = 123456.789;
// 默认格式化
console.log(new Intl.NumberFormat().format(number)); // "123,456.789"
// 指定语言环境
console.log(new Intl.NumberFormat("zh-CN").format(number)); // "123,456.789"
console.log(new Intl.NumberFormat("de-DE").format(number)); // "123.456,789"
console.log(new Intl.NumberFormat("en-US").format(number)); // "123,456.789"
// 货币格式化
console.log(new Intl.NumberFormat("zh-CN", {
style: "currency",
currency: "CNY"
}).format(number)); // "¥123,456.79"
console.log(new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD"
}).format(number)); // "$123,456.79"
console.log(new Intl.NumberFormat("de-DE", {
style: "currency",
currency: "EUR"
}).format(number)); // "123.456,79 €"
// 百分比格式化
console.log(new Intl.NumberFormat("zh-CN", {
style: "percent"
}).format(0.1234)); // "12%"
console.log(new Intl.NumberFormat("zh-CN", {
style: "percent",
minimumFractionDigits: 2
}).format(0.1234)); // "12.34%"
// 单位格式化
console.log(new Intl.NumberFormat("zh-CN", {
style: "unit",
unit: "kilometer"
}).format(12.345)); // "12.345公里"
console.log(new Intl.NumberFormat("zh-CN", {
style: "unit",
unit: "kilogram",
maximumFractionDigits: 2
}).format(12.345)); // "12.35公斤"
// 紧凑格式
console.log(new Intl.NumberFormat("zh-CN", {
notation: "compact"
}).format(123456789)); // "1.2亿"
console.log(new Intl.NumberFormat("zh-CN", {
notation: "compact",
compactDisplay: "long"
}).format(123456789)); // "1.2亿"
// 工程格式
console.log(new Intl.NumberFormat("zh-CN", {
notation: "engineering"
}).format(123456789)); // "123.457E6"
// 科学格式
console.log(new Intl.NumberFormat("zh-CN", {
notation: "scientific"
}).format(123456789)); // "1.235E8"
// 精度控制
console.log(new Intl.NumberFormat("zh-CN", {
minimumIntegerDigits: 3,
minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(5)); // "005.00"
// 数字系统
console.log(new Intl.NumberFormat("zh-CN-u-nu-hanidec").format(12345));
// "一二三四五"
// 负数格式
console.log(new Intl.NumberFormat("zh-CN", {
signDisplay: "always"
}).format(-42)); // "-42"
console.log(new Intl.NumberFormat("zh-CN", {
signDisplay: "exceptZero"
}).format(0)); // "0"数学运算工具
高精度计算
javascript
class MathUtils {
// 精确加法
static add(a, b) {
const factor = 10;
return (a * factor + b * factor) / factor;
}
// 精确减法
static subtract(a, b) {
const factor = 10;
return (a * factor - b * factor) / factor;
}
// 精确乘法
static multiply(a, b) {
const factor = 100;
return (a * factor * b * factor) / (factor * factor);
}
// 精确除法
static divide(a, b, precision = 10) {
return parseFloat((a / b).toFixed(precision));
}
// 计算百分比
static percentage(value, total) {
return (value / total) * 100;
}
// 计算折扣价格
static discountPrice(originalPrice, discountPercent) {
return originalPrice * (1 - discountPercent / 100);
}
// 计算增长率
static growthRate(oldValue, newValue) {
return ((newValue - oldValue) / oldValue) * 100;
}
// 计算平均值
static average(numbers) {
if (numbers.length === 0) return 0;
return numbers.reduce((sum, num) => sum + num, 0) / numbers.length;
}
// 计算中位数
static median(numbers) {
const sorted = [...numbers].sort((a, b) => a - b);
const middle = Math.floor(sorted.length / 2);
if (sorted.length % 2 === 0) {
return (sorted[middle - 1] + sorted[middle]) / 2;
}
return sorted[middle];
}
// 计算众数
static mode(numbers) {
const frequency = {};
let maxFreq = 0;
let mode = [];
numbers.forEach(num => {
frequency[num] = (frequency[num] || 0) + 1;
if (frequency[num] > maxFreq) {
maxFreq = frequency[num];
}
});
for (const num in frequency) {
if (frequency[num] === maxFreq) {
mode.push(parseFloat(num));
}
}
return mode;
}
// 计算标准差
static standardDeviation(numbers) {
const mean = this.average(numbers);
const squaredDifferences = numbers.map(num => Math.pow(num - mean, 2));
const averageSquaredDifference = this.average(squaredDifferences);
return Math.sqrt(averageSquaredDifference);
}
// 计算阶乘
static factorial(n) {
if (n < 0) return NaN;
if (n === 0 || n === 1) return 1;
let result = 1;
for (let i = 2; i <= n; i++) {
result *= i;
}
return result;
}
// 计算最大公约数
static gcd(a, b) {
a = Math.abs(a);
b = Math.abs(b);
while (b !== 0) {
const temp = b;
b = a % b;
a = temp;
}
return a;
}
// 计算最小公倍数
static lcm(a, b) {
return Math.abs(a * b) / this.gcd(a, b);
}
// 判断是否为偶数
static isEven(num) {
return num % 2 === 0;
}
// 判断是否为奇数
static isOdd(num) {
return num % 2 !== 0;
}
// 判断是否为正数
static isPositive(num) {
return num > 0;
}
// 判断是否为负数
static isNegative(num) {
return num < 0;
}
// 判断是否为零
static isZero(num) {
return num === 0;
}
}
// 使用示例
console.log(MathUtils.add(0.1, 0.2)); // 0.3
console.log(MathUtils.subtract(0.3, 0.1)); // 0.2
console.log(MathUtils.multiply(0.1, 0.2)); // 0.02
console.log(MathUtils.divide(0.3, 0.1)); // 3
console.log(MathUtils.percentage(25, 100)); // 25
console.log(MathUtils.discountPrice(100, 20)); // 80
console.log(MathUtils.growthRate(100, 120)); // 20
const numbers = [1, 2, 3, 4, 5, 5, 6];
console.log(MathUtils.average(numbers)); // 3.7142857142857144
console.log(MathUtils.median(numbers)); // 4
console.log(MathUtils.mode(numbers)); // [5]
console.log(MathUtils.standardDeviation(numbers)); // 1.6035674514745464
console.log(MathUtils.factorial(5)); // 120
console.log(MathUtils.gcd(12, 18)); // 6
console.log(MathUtils.lcm(12, 18)); // 36
console.log(MathUtils.isEven(4)); // true
console.log(MathUtils.isOdd(3)); // true
console.log(MathUtils.isPositive(5)); // true
console.log(MathUtils.isNegative(-5)); // true
console.log(MathUtils.isZero(0)); // true实际应用示例
1. 货币计算工具
javascript
class CurrencyCalculator {
constructor(currency = "CNY", locale = "zh-CN") {
this.currency = currency;
this.locale = locale;
this.formatter = new Intl.NumberFormat(locale, {
style: "currency",
currency: currency
});
}
// 格式化货币
format(amount) {
return this.formatter.format(amount);
}
// 加法
add(...amounts) {
return amounts.reduce((sum, amount) => sum + amount, 0);
}
// 减法
subtract(minuend, ...subtrahends) {
return subtrahends.reduce((result, subtrahend) => result - subtrahend, minuend);
}
// 乘法
multiply(amount, multiplier) {
return amount * multiplier;
}
// 除法
divide(dividend, divisor) {
if (divisor === 0) {
throw new Error("除数不能为零");
}
return dividend / divisor;
}
// 计算折扣
applyDiscount(amount, discountPercent) {
return amount * (1 - discountPercent / 100);
}
// 计算税费
applyTax(amount, taxRate) {
return amount * (1 + taxRate / 100);
}
// 计算小费
calculateTip(amount, tipPercent) {
return amount * (tipPercent / 100);
}
// 分摊费用
splitBill(totalAmount, numberOfPeople) {
return totalAmount / numberOfPeople;
}
// 货币转换(模拟)
convert(amount, fromCurrency, toCurrency, exchangeRate) {
return amount * exchangeRate;
}
// 计算复利
compoundInterest(principal, rate, time, compoundFrequency = 1) {
return principal * Math.pow(1 + (rate / 100) / compoundFrequency, compoundFrequency * time);
}
// 计算简单利息
simpleInterest(principal, rate, time) {
return principal * (rate / 100) * time;
}
// 计算贷款月供
loanPayment(principal, annualRate, months) {
const monthlyRate = (annualRate / 100) / 12;
return (principal * monthlyRate * Math.pow(1 + monthlyRate, months)) /
(Math.pow(1 + monthlyRate, months) - 1);
}
}
// 使用示例
const calculator = new CurrencyCalculator("CNY", "zh-CN");
const price = 100;
const discountedPrice = calculator.applyDiscount(price, 20); // 20% 折扣
const priceWithTax = calculator.applyTax(discountedPrice, 13); // 13% 税费
const tip = calculator.calculateTip(priceWithTax, 10); // 10% 小费
const total = calculator.add(priceWithTax, tip);
console.log("原价:", calculator.format(price)); // "¥100.00"
console.log("折扣后:", calculator.format(discountedPrice)); // "¥80.00"
console.log("含税价:", calculator.format(priceWithTax)); // "¥90.40"
console.log("小费:", calculator.format(tip)); // "¥9.04"
console.log("总计:", calculator.format(total)); // "¥99.44"
// 分摊费用
const billTotal = 200;
const people = 4;
const perPerson = calculator.splitBill(billTotal, people);
console.log(`每人应付: ${calculator.format(perPerson)}`); // "每人应付: ¥50.00"
// 贷款计算
const loanAmount = 100000; // 10万元
const annualRate = 5; // 年利率5%
const loanTerm = 120; // 10年(120个月)
const monthlyPayment = calculator.loanPayment(loanAmount, annualRate, loanTerm);
console.log(`月供: ${calculator.format(monthlyPayment)}`); // "月供: ¥1,060.66"2. 统计分析工具
javascript
class StatisticalAnalyzer {
constructor(data) {
this.data = Array.isArray(data) ? data : [data];
}
// 基本统计量
getBasicStats() {
if (this.data.length === 0) return null;
const sorted = [...this.data].sort((a, b) => a - b);
const sum = this.data.reduce((acc, val) => acc + val, 0);
const mean = sum / this.data.length;
return {
count: this.data.length,
sum: sum,
mean: mean,
median: this.getMedian(sorted),
mode: this.getMode(),
min: sorted[0],
max: sorted[sorted.length - 1],
range: sorted[sorted.length - 1] - sorted[0]
};
}
// 获取中位数
getMedian(sortedData) {
const middle = Math.floor(sortedData.length / 2);
if (sortedData.length % 2 === 0) {
return (sortedData[middle - 1] + sortedData[middle]) / 2;
}
return sortedData[middle];
}
// 获取众数
getMode() {
const frequency = {};
let maxFreq = 0;
let modes = [];
this.data.forEach(num => {
frequency[num] = (frequency[num] || 0) + 1;
if (frequency[num] > maxFreq) {
maxFreq = frequency[num];
}
});
for (const num in frequency) {
if (frequency[num] === maxFreq) {
modes.push(parseFloat(num));
}
}
return modes.length === this.data.length ? [] : modes;
}
// 方差
getVariance() {
if (this.data.length === 0) return 0;
const mean = this.getBasicStats().mean;
const squaredDifferences = this.data.map(num => Math.pow(num - mean, 2));
return squaredDifferences.reduce((sum, val) => sum + val, 0) / this.data.length;
}
// 标准差
getStandardDeviation() {
return Math.sqrt(this.getVariance());
}
// 四分位数
getQuartiles() {
if (this.data.length === 0) return null;
const sorted = [...this.data].sort((a, b) => a - b);
const n = sorted.length;
const q1Index = Math.floor(n * 0.25);
const q2Index = Math.floor(n * 0.5);
const q3Index = Math.floor(n * 0.75);
return {
q1: sorted[q1Index],
q2: sorted[q2Index], // 中位数
q3: sorted[q3Index],
iqr: sorted[q3Index] - sorted[q1Index] // 四分位距
};
}
// 百分位数
getPercentile(percentile) {
if (this.data.length === 0) return null;
if (percentile < 0 || percentile > 100) return null;
const sorted = [...this.data].sort((a, b) => a - b);
const index = (percentile / 100) * (sorted.length - 1);
const lowerIndex = Math.floor(index);
const upperIndex = Math.ceil(index);
if (lowerIndex === upperIndex) {
return sorted[lowerIndex];
}
const weight = index - lowerIndex;
return sorted[lowerIndex] * (1 - weight) + sorted[upperIndex] * weight;
}
// Z 分数
getZScore(value) {
const stats = this.getBasicStats();
const stdDev = this.getStandardDeviation();
if (stdDev === 0) return 0;
return (value - stats.mean) / stdDev;
}
// 偏度
getSkewness() {
if (this.data.length < 3) return 0;
const mean = this.getBasicStats().mean;
const stdDev = this.getStandardDeviation();
const n = this.data.length;
if (stdDev === 0) return 0;
const sumCubedDeviations = this.data.reduce(
(sum, val) => sum + Math.pow((val - mean) / stdDev, 3),
0
);
return (n / ((n - 1) * (n - 2))) * sumCubedDeviations;
}
// 峰度
getKurtosis() {
if (this.data.length < 4) return 0;
const mean = this.getBasicStats().mean;
const stdDev = this.getStandardDeviation();
const n = this.data.length;
if (stdDev === 0) return 0;
const sumFourthDeviations = this.data.reduce(
(sum, val) => sum + Math.pow((val - mean) / stdDev, 4),
0
);
const factor = (n * (n + 1)) / ((n - 1) * (n - 2) * (n - 3));
const subtractor = (3 * (n - 1) * (n - 1)) / ((n - 2) * (n - 3));
return factor * sumFourthDeviations - subtractor;
}
// 频率分布
getFrequencyDistribution(bins = 10) {
if (this.data.length === 0) return [];
const stats = this.getBasicStats();
const binWidth = (stats.max - stats.min) / bins;
const distribution = [];
for (let i = 0; i < bins; i++) {
const binMin = stats.min + i * binWidth;
const binMax = stats.min + (i + 1) * binWidth;
const count = this.data.filter(
val => val >= binMin && val < binMax
).length;
// 最后一个区间包含最大值
if (i === bins - 1) {
const lastCount = this.data.filter(
val => val >= binMin && val <= binMax
).length;
distribution.push({
range: `${binMin.toFixed(2)} - ${binMax.toFixed(2)}`,
count: lastCount,
percentage: (lastCount / this.data.length) * 100
});
} else {
distribution.push({
range: `${binMin.toFixed(2)} - ${binMax.toFixed(2)}`,
count: count,
percentage: (count / this.data.length) * 100
});
}
}
return distribution;
}
// 异常值检测
getOutliers(method = "iqr") {
if (method === "iqr") {
const quartiles = this.getQuartiles();
const iqr = quartiles.iqr;
const lowerBound = quartiles.q1 - 1.5 * iqr;
const upperBound = quartiles.q3 + 1.5 * iqr;
return this.data.filter(
val => val < lowerBound || val > upperBound
);
} else if (method === "zscore") {
const threshold = 3;
return this.data.filter(
val => Math.abs(this.getZScore(val)) > threshold
);
}
return [];
}
}
// 使用示例
const testData = [1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 10, 10, 15, 20, 25, 30];
const analyzer = new StatisticalAnalyzer(testData);
console.log("基本统计量:", analyzer.getBasicStats());
console.log("方差:", analyzer.getVariance());
console.log("标准差:", analyzer.getStandardDeviation());
console.log("四分位数:", analyzer.getQuartiles());
console.log("75百分位数:", analyzer.getPercentile(75));
console.log("Z分数 (值为15):", analyzer.getZScore(15));
console.log("偏度:", analyzer.getSkewness());
console.log("峰度:", analyzer.getKurtosis());
console.log("频率分布:", analyzer.getFrequencyDistribution(5));
console.log("异常值 (IQR方法):", analyzer.getOutliers("iqr"));
console.log("异常值 (Z分数方法):", analyzer.getOutliers("zscore"));总结
JavaScript Number 对象的核心要点:
- 基本概念:数字是基本类型,Number 是其包装对象
- 创建方式:字面量、构造函数、Number() 函数
- 静态属性:EPSILON、MAX_VALUE、MIN_VALUE、安全整数范围等
- 静态方法:isFinite()、isNaN()、isInteger()、parseInt()、parseFloat()
- 实例方法:toFixed()、toExponential()、toPrecision()、toString()
- 精度问题:浮点数精度问题及解决方案
- 大数支持:BigInt 对象处理大整数
- 格式化:Intl.NumberFormat 进行本地化格式化
- 数学工具:自定义工具类处理各种数学运算
- 实际应用:货币计算、统计分析等场景
掌握 Number 对象的各种特性和方法对于进行精确的数值计算和数据处理非常重要。在下一章节中,我们将学习 JavaScript 的 Math 对象。