面试Coding-请使用JS把任意一个金额转换为千分位格式

43 阅读3分钟

JS虐我千百遍,我待JS如初恋,冲啊!

今日面试总结:写两道js的基础题,听起来挺简单,但是需要注意很多细节

第一题:请使用JS把任意一个金额转换为千分位格式

function formatWithCommas(num) {
    // 处理非数字情况
    if (typeof num !== 'number' && typeof num !== 'string') {
        return '';
    }
    
    // 转换为字符串以便处理
    let str = typeof num === 'number' ? num.toString() : num;
    
    // 分离正负号
    let sign = '';
    if (str[0] === '+' || str[0] === '-') {
        sign = str[0];
        str = str.slice(1);
    }
    
    // 分离整数和小数部分
    let [integerPart, decimalPart] = str.split('.');
    
    // 处理整数部分的千分位
    let formattedInteger = '';
    let count = 0;
    
    // 从右向左遍历,每三位添加一个逗号
    for (let i = integerPart.length - 1; i >= 0; i--) {
        formattedInteger = integerPart[i] + formattedInteger;
        count++;
        // 每三位添加一个逗号,但不要在开头添加
        if (count % 3 === 0 && i !== 0) {
            formattedInteger = ',' + formattedInteger;
        }
    }
    
    // 组合结果:符号 + 格式化的整数部分 + 小数部分(如果有)
    let result = sign + formattedInteger;
    if (decimalPart !== undefined) {
        result += '.' + decimalPart;
    }
    
    return result;
}

// 测试用例
console.log(formatWithCommas(1234567)); // "1,234,567"
console.log(formatWithCommas(1234567.89)); // "1,234,567.89"
console.log(formatWithCommas(-12345)); // "-12,345"
console.log(formatWithCommas("1234567890")); // "1,234,567,890"
console.log(formatWithCommas(0)); // "0"
console.log(formatWithCommas(123.456789)); // "123.456789"
console.log(formatWithCommas("+9876543.21")); // "+9,876,543.21"

第二题:使用循环实现一个对象深拷贝,老生常谈的js基础题了,看看怎么写吧?

function deepClone(source) {
    // 处理基本类型和null
    if (source === null || typeof source !== 'object') {
        return source;
    }

    // 存储待处理的节点和对应的克隆结果
    const stack = [];
    // 初始化克隆对象/数组
    const root = Array.isArray(source) ? [] : {};
    stack.push({
        parent: null,
        key: null,
        data: source,
        clone: root
    });

    // 循环处理栈中的节点
    while (stack.length > 0) {
        const node = stack.pop();
        const { parent, key, data, clone } = node;

        // 遍历当前数据的所有属性
        for (const prop in data) {
            if (data.hasOwnProperty(prop)) {
                const value = data[prop];
                
                // 基本类型直接赋值
                if (value === null || typeof value !== 'object') {
                    clone[prop] = value;
                    continue;
                }

                // 处理数组
                const isArray = Array.isArray(value);
                const childClone = isArray ? [] : {};
                clone[prop] = childClone;

                // 将子节点推入栈中等待处理
                stack.push({
                    parent: clone,
                    key: prop,
                    data: value,
                    clone: childClone
                });
            }
        }
    }

    return root;
}

// 测试用例
const original = {
    name: "测试",
    age: 25,
    hobbies: ["读书", "运动"],
    address: {
        city: "北京",
        district: "朝阳区",
        coordinates: {
            x: 116,
            y: 39
        }
    },
    isStudent: false,
    scores: null
};

const cloned = deepClone(original);

// 修改原对象的嵌套属性,验证深拷贝效果
original.address.city = "上海";
original.hobbies.push("编程");

console.log(original.address.city); // 上海(原对象被修改)
console.log(cloned.address.city);  // 北京(克隆对象未受影响)
console.log(original.hobbies);     // ["读书", "运动", "编程"]
console.log(cloned.hobbies);       // ["读书", "运动"]

第三题:写一个方法:比较两个对象是否相等

function isObject(value) {
  return typeof value === 'object' && value !== null && !Array.isArray(value);
}

function isArrayEqual(arr1, arr2) {
  if (arr1.length !== arr2.length) return false;
  return arr1.every((item, index) => objectEquals(item, arr2[index]));
}
// 比较对象是否相等
function objectEquals(obj1, obj2) {
  // 基本类型直接比较
  if (obj1 === obj2) return true;
  
  // 处理null和非对象类型
  if (obj1 === null || obj2 === null) return false;
  if (typeof obj1 !== 'object' || typeof obj2 !== 'object') return false;
  
  // 处理数组
  if (Array.isArray(obj1) && Array.isArray(obj2)) {
    return isArrayEqual(obj1, obj2);
  }
  
  // 非数组对象但类型不同
  if (Array.isArray(obj1) || Array.isArray(obj2)) return false;
  
  // 获取对象键并比较数量
  const keys1 = Object.keys(obj1);
  const keys2 = Object.keys(obj2);
  if (keys1.length !== keys2.length) return false;
  
  // 递归比较每个属性
  return keys1.every(key => {
    if (!keys2.includes(key)) return false;
    return objectEquals(obj1[key], obj2[key]);
  });
}

大家好,我是阿慧,一个正在被面试折磨的前端开发~ 记录一下我的经历,也希望能帮助你一点点~