Skip to content

类型转换

强制类型转换

  • parseIntparseFloatNumber...
  • parseInt会从左往右提取有效位的数字
js
parseInt('10') // 10
parseInt('10px') // 10
parseInt('n10px') // NaN

parseInt(27.2,0) // 27
parseInt(0,1) // NaN 基数为2-32,除此都是返回NaN
parseInt('0013',2) // 001看做2进制 转换为10进制(1*2^0 -> 1)
parseInt('14px',3) // 1看做3进制 转换为10进制(1*3^0 -> 1)
parseInt(123,4) // 123看做4进制 转换为10进制(1*4^2=16  2*4^1 = 8  3*4^0=3)

一元+符号会转数字(隐式)

  • ES6的 bigIntSymbol 不能+转数字 报错
  • +null= 0+undefined = NaN +{} = NaN
js
console.log(+null); // 0
console.log(+undefined); // NaN
console.log(+1); // 1
console.log(+"123aa"); // NaN
console.log(+{}); // NaN
console.log(+true); // 1

// ES6的 bigInt和Symbol 不能+转数字 报错
console.log(10n);
console.log(Symbol.for("a"));

if 判断属性

  • if判断时undefined,null,NaN,0,'' 在运算时都是 false
js
const result = {};
const obj = {name:0} // OR undefined null NaN 0 ''
// 会存在问题
// 应该用obj.hasOwnProperty(name)来判断
if (obj.name) {
  result.name = obj.name;
}
return result;

一元符号(!)

  • 可将变量转换成 boolean 类型,nullundefinedNaN0 以及空字符串('')取反都为 true,其余都为 false

==比较会隐士类型转换

  • null 只能和 undefined==时相等,除此和他任何类型都不相等(==)
  • NaN 和谁都不相等包括自己
  • 布尔类型和其他类型相等比较,布尔会转换成数字类型
  • 数字类型字符类型相等比较,字符会转换成数字类型
  • 对象类型原始类型比较,对象类型会转换成原始类型
  • 对象类型和象类型比较,比较引用地址
js
console.log(null == undefined); // true
console.log(null == 0); // false
console.log("0" == false); // true
console.log([] == ![]); // true
console.log("000" == 0); // true
console.log([true] == 1); // false

二元操作符号(+)规则

  • 如果是对象,则对象会转成原始类型
  • 如果其中一个操作符是字符串另一个会转换成字符串,进行字符串拼接
  • 否则,两个操作数都将转换成数字或者 NaN,进行加法操作
js
console.log([] + []); // ''
console.log([] + {}); // [object Object]
console.log({} + []); // [object Object]
console.log({} + {}); // [object Object][object Object] =>({}+{})

对象二元+操作

  • 1、对象二元+的运用,会进行隐士转换
  • 2、在没有 Symbol.toPrimitive 的情况下
  • 3、优先调用 自身的 valueOf,自身没有调用原型的 valueOf,如果返回的不是原始类型
  • 4、也是调用 优先调用 自身的 toString,自身没有调用原型的,返回的不是原始类型会报错
js
let a = {
  [Symbol.toPrimitive](hint) {
    console.log("hint", hint);
    return {};
  },
  toString() {
    console.log("toString");
    return {};
  },
  valueOf() {
    console.log("valueOf");
    return {};
  },
};

console.log(a + []); // ncaught TypeError: Cannot convert object to primitive value

对象 toPrimitive,valueof,toString 隐士转换规则

imgimgimgimg

valueOf or toString

js
// Array
let arr = [1, 2, 5];
// Object
let user = {
  name: "Jason",
  age: 24,
};
// Date 返回时间撮
let now = new Date();
// Function
function fun() {
  return 10;
}

// valueOf
console.log("Array:", arr.valueOf()); //  [ 1, 2, 5 ]
console.log("Object:", user.valueOf()); // { name: 'Jason', age: 24 }
console.log("Date:", now.valueOf()); // 1666426494197
console.log("Function:", fun.valueOf()); // [Function: fun]

// toString
console.log("Array:", arr.toString()); //  1,2,5
console.log("Object:", user.toString()); // [object Object]
console.log("Date:", now.toString()); // Date: Sat Oct 22 2022 16:17:11 GMT+0800 (China Standard Time)
console.log("Function:", fun.toString()); // function fun() { return 10 }

对象对比误区

  • 对象对比的是地址,不会隐士类型转换(不会调用 toPrimitive、toString、valueOf)
js
const obj1 = {
  [Symbol.toPrimitive](hint) {
    if (hint == "number") {
      return 10;
    }
    if (hint == "string") {
      return "hello";
    }

    return true;
  },
};

const obj2 = {
  [Symbol.toPrimitive](hint) {
    if (hint == "number") {
      return 10;
    }
    if (hint == "string") {
      return "hello";
    }
    return true;
  },
};

console.log("宽松比较: 对象和数字", obj1 == true); // true
console.log("宽松比较 两个对象:", obj1 == obj2); // false 对象对比不会进行隐士类型转换,对比的地址
console.log("严等:", obj1 === obj2); // false
console.log("不等:", obj1 != obj2); // true

隐士转换核心题目

js
const arr = [4, 10];
arr[Symbol.toPrimitive] = function (hint) {
  return hint;
};
arr.valueOf = function () {
  return this;
};

const obj = {};
// 1、+number => NaN (有toPrimitive先调用返回number字符,字符转数字NaN)
// 2、NaN + [object object] => 2、NaN[object object] (对象调用toString=[object object])
// 3、NaN[object object] + default => NaN[object object]default
// 4、NaN[object object]default + [object object] => NaN[object object]default[object object]

console.log(+arr + obj + arr + obj); // NaN[object object]default[object object]

console.log({} + arr); // [object Object]default
js
// null、undefined、NaN 以及空字符串('')取反都为 true,其余都为 false。
const val = [] == ![];
console.log(val); // true
console.log([+val, [] + 1] == [1, 1] + []); // true
"1,1" == "1,1";

console.log([+val, [] + 1] == [1, "1"]); // false
js
const val = (+{} + [])[+[]]; // => NaN[0]
console.log(val); // N