[Day17] 强制转型

因 JavaScript 在执行阶段时,型别可不断转换,而这些型别的转换又可分为 明确的强制转型,以及在昨天 Day16 - 严格相等 vs 宽松相等 中有谈到 隐含的强制转型,详细如下:

明确的强制转型

在程序码中特意写出来转换型别,就称为 明确的强制转型

console.log(String(1)); // 1 - 字串型别 => 数字转字串 

隐含的强制转型

当并未在程序码中明确指出要转换型别却转换了,就称为 隐含的强制转型

console.log( 1 + '1'); // 11 - 字串型别

加减乘除与取余数的转型

除了 严格相等宽松相等 会转型外,使用其他的 运算子 也会使值做转型,以下以加减乘除与取余数为例:

加号

范例1 - 布林、Null、undefined 与数值相加

除字串型别、物件外,与数值相加时,会先转为数字型别再相加

// 数值 + 数值
console.log(1 + 1); // 2

// 布林 + 数值
console.log(Number(true)); // 1
console.log(1 + true); // 2

// null + 数值
console.log(Number(null)); // 0
console.log(1 + null); // 1

// undefined + 数值
console.log(Number(undefined)); // NaN
console.log(1 + undefined); // NaN

// 包裹物件 + 数值
console.log(new Number(1)); // Number {1}
console.log(1 + new Number(1)); // 2

范例2 - 字串、物件与数值相加

范例2-1

当字串、物件与数值相加时

  • 数值会先转为字串,再与字串相加
  • 物件会使用原型方法中的 .toString() 转换成字串,而数值也转换成字串再相加
// 字串 + 数值
console.log(1 + '1'); // 11
console.log(1 + 'a'); // 1a
 
// 物件 + 数值
console.log(1 + [1]); // 11
console.log(1 + {1: 1}); // 1[object Object]
范例2-2

Day15 - 优先性与相依性 有谈到 优先性相依性,故在此范例中,都是 + 运算子,优先性相同,而相依性为由左至右,所以会先执行 '英文 60 分、中文 80 分,总分为: ' + english 得出 英文 60 分、中文 80 分,总分为: 60 再与 80 相加

var english = 60;
var chinese = 80;
console.log('英文 60 分、中文 80 分,总分为: ' + english + chinese);
// 英文 60 分、中文 80 分,总分为: 6080

范例3 - undefined、null、布林与字串相加

当 undefined、null、布林与字串相加,布林 、null 与 undefined 会使用 String(),分别转换成字串後再相加

//  undefined + 字串
console.log(undefined + 'a'); // undefined

//  null + 字串
console.log(null + 'a'); // nulla

//  布林 + 字串
console.log(true + 'a'); // truea

减号

字串、布林、undefined、null 若与数值相减,会先使用 Number() 转成数值再做计算
物件则使用 valueOf() 计算或使用 .toString() 先转为字串再转数字

console.log(1 - 1); // 0
console.log(1 - '1'); // 0
console.log(1 - 'a'); // NaN
console.log(1 - true); // 0
console.log(1 - false); // 1
console.log(1 - undefined); // 因 undefined 转数字为 NaN,结果为 NaN 
console.log(1 - null); // null 转数字为 0,1-0 = 1

console.log(1 - {}); // {} 转成字串为 [object, object] 後再计算 => NaN
console.log(1 - []); // 1
console.log(1 - [1]); // 0
console.log(1 - ['1']); // 0

console.log(1 - new Number(1)); // 0

乘号

若乘号其中一个非数值,则会先转为数值再计算

console.log(2 * 2); // 4
console.log(2 * '2'); // 4
console.log(2 * 'a'); // NaN
console.log(2 * true); // 2
console.log(2 * false); // 0
console.log(2 * null); // null 转数字为 0,2*0 = 0
console.log(2 * undefined); // 因 undefined 转数字为 NaN,结果为 NaN 

console.log(2 * {}); // NaN
console.log(2 * []); // 0
console.log(2 * [2]); // 4
console.log(2 * ['2']); // 4

console.log(2 * new Number(2)); // 4

除号

若其中一个非数值,则会先转为数值再计算

console.log(4 / 2); // 2
console.log(0 / 2); // 0
console.log('a' / 2); // NaN
console.log('4' / 2); // 2
console.log(true / 2); // 0.5
console.log(false / 2); // 0
console.log(null / 2); // null 转数字为 0,0/0=0
console.log(undefined / 2); // 因 undefined 转数字为 NaN,结果为 NaN 

console.log({} / 2); // NaN
console.log([] / 2); // 0
console.log([4] / 2); // 2
console.log(['4'] / 2); // 2

console.log(new Number(4) / 2); // 2

若被除数为 0,则结果为 Infinity

console.log(4 / 2); // 2
console.log(4 / 0); // 被除数为 0,结果为 Infinity
console.log(4 / 'a'); // NaN
console.log(4 / '2'); // 2
console.log(4 / true); // 4
console.log(4 / false); // false 转数字为 0,结果为 Infinity
console.log(4 / null); // null 转数字为 0,结果为 Infinity
console.log(4 / undefined); // 因 undefined 转数字为 NaN,结果为 NaN 

console.log(4 / {}); // NaN
console.log(4 / []); // Infinity
console.log(4 / [2]); // 2
console.log(4 / ['2']); // 2

console.log(4 / new Number(2)); // 2

取余数(%)

% 取余数的规则与除法相似

console.log(5 % 2); // 1
console.log(0 % 2); // 0
console.log('a' % 2); // NaN
console.log('5' % 2); // 1
console.log(true % 2); // 1%2 = 1
console.log(false % 2); // 0%2 = 0
console.log(null % 2); // 0%2 = 0
console.log(undefined % 2); // 因 undefined 转数字为 NaN,结果为 NaN 

console.log({} % 2); // NaN
console.log([] % 2); // 0%2 = 0
console.log([5] % 2); // 1
console.log(['5'] % 2); // 1

console.log(new Number(5) % 2); // 1

若被除数为 0,则取余数结果为 NaN

console.log(5 % 2); // 1
console.log(5 % 0); // NaN
console.log(5 % 'a'); // NaN
console.log(5 % '2'); // 1
console.log(5 % true); // 5/1 = 0
console.log(5 % false); // 5/0 = NaN
console.log(5 % null); // 5/0 = NaN
console.log(5 % undefined); // 因 undefined 转数字为 NaN,结果为 NaN 

console.log(5 % {}); // NaN
console.log(5 % []); // NaN
console.log(5 % [2]); // 1
console.log(5 % ['2']); // 1

console.log(5 % new Number(2)); // 1

NaN 的加减乘除

undefined 转数值会为 NaN,所以以下举出一些 NaN 加减乘除所得出的结果

NaN 加减乘除数值所得出的结果

如果其中一个是 NaN 的话,那麽结果会为 NaN

console.log(NaN + 2); // NaN
console.log(NaN - 2); // NaN
console.log(NaN * 2); // NaN
console.log(NaN / 2); // NaN
console.log(2 / NaN); // NaN
console.log(NaN % 2); // NaN
console.log(2 % NaN); // NaN

NaN 加减乘除其他型别所得出的结果

在加减乘除中,除了 NaN字串型别 相加可得到字串外,其他结果皆为 NaN

console.log(NaN + 1); // NaN
console.log(NaN + '1'); // NaN1 - 字串型别
console.log(NaN + true); // NaN
console.log(NaN + null); // NaN
console.log(NaN + undefined); // NaN

console.log(NaN - 1); // NaN
console.log(NaN - '1'); // NaN
console.log(NaN - true); // NaN
console.log(NaN - null); // NaN
console.log(NaN - undefined); // NaN

console.log(NaN * 1); // NaN
console.log(NaN * '1'); // NaN
console.log(NaN * true); // NaN
console.log(NaN * null); // NaN
console.log(NaN * undefined); // NaN

console.log(NaN / 1); // NaN
console.log(NaN / '1'); // NaN
console.log(NaN / true); // NaN
console.log(NaN / null); // NaN
console.log(NaN / undefined); // NaN

参考文献

Summer - 强制转型

Kuro - 运算式与运算子


<<:  [Day 22] 2D批次渲染 (三) - 终於找到问题了

>>:  [Day17] 建立订单交易API_10

28. 解释 CSS Box Model ( box-sizing )

今天也是复习CSS,是非常之基础的box-sizing。 Box Model 前一篇文提到,HTML...

第32天~

这个的上一篇在https://ithelp.ithome.com.tw/articles/10233...

堆叠 - 四则运算 - DAY 8

标准四则运算(中缀运算式)转尾缀运算式 9-3/3+(4+5)*2 尾缀运算式算出答案 ...

【领域展开 20 式】 Menu 修炼失败纪录手册

更动 Menu 大作战 暨【领域展开 13 式】 有了骨头与皮肤,再搞清楚主要肌群 Menu 层级与...

DAY18-EXCEL统计分析:T检定实例

让我们用前两天Z检定的相同题目来试一次T检定 有一家3C公司说自家品牌的手机均可以使用超过5年,而标...