VueBloghyhero6

NaN 不等于NaN 以及 变量判断陷阱

2020-05-28 / 2020-05-28 / 367次浏览

网上找到的基本答案

NaN 即 Not a Number( 非数值 ),但它是一个特殊的数值,所以:

typeof( NaN ) // 'number'

编码时很少直接使用NaN,通常是在计算失败时,作为Math的某个方法的返回值出现的。

它有重要的俩个性质:

NaN 与 任何值都不相等,包括NaN 自身

任何 涉及 NaN 的操作都会返回NaN.

1.计算

JS 在进行加减乘除运算之前,会先调用 Number() 方法,将非数值运算项转换为数值,如果转换失败就返回NaN,例如说

1 - 'a'; // NaN

首先是 执行Number('a'),不能成功转化为数值,返回NaN,再利用NaN的第二条性质:任何涉及NaN的操作都会返回NaN,所以最终的结果 是 NaN.

2.类型 转换

当一个值不能被Number,parseInt,parseFloat 成功转换为数值,就返回NaN

然后 isNaN 的实现,原理就是利用NaN 的第一条性质:NaN 与 任何 值都不相等,包括NaN 本身。

var isNaNA = funtion( value ){
var n = Number( value );
return n != n;
}

先用Number 转换参数,再判断转换后的结果是不是不等于自身。 然而MDN 给出的结果是这样的

想要只是判断NaN 貌似也是有办法的 ES6 中给出了方案。

这片文章的 主觉得有问题。

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Data_structures

继续接着说 变量判断陷阱

编程语言都具有内建的数据结构,但各种编程语言的数据结构常有不同之处。

JavaScript 是一种弱类型或者说动态语言。这意味着你不用提前声明变量类型,在程序运行过程中,类型会被自动确定。这也就意味着你可以使用同一个变量保存不同类型的数据:

var foo = 42;

foo = 'bar'

foo = 'true'

面试一般说6种

ECMAScript 已经给出了7种, Symbol 也是一种。

typeof 陷阱


这里 typeof arr = [] 判断一个数组它是一个对象,判断一个null 它也是一个对象。

instanceof 的陷阱 和 基本包装类型

instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的prototype 属性。

基本包装类型

javascript 为了方便操作基本类型值,ECMAscript 提供了 3个特殊的引用类型:Boolean,Number 和 String。每当读取一个基本类型的时候,后台就会创建一个对应的基本包装类型的对象。从而让我们能够调用一些方法来操作这些数据。

var s1 = 'some text';

var s2 = s1.substring(2);

上面代码中,先创建了一个字符串保存在了变量s1, 字符串当然是基本值类型。但是在下一行中我们又调用了s1 的方法。我们知道基本类型不是对象,理论上它不应该有方法(但是它确实有方法)。其实,为了让我们实现这种直观操作,后台已经帮助我们完成了一系列的操作。当我们在第二行代码中访问S1 变量的时候,访问过程处于读取模式, 而在读取模式中访问字符串时,后台都会自动完成下面处理。

1.创建String类型上的一个实例

2.在实例上调用指定的方法

3.销毁这个实例

可以将以上三个步骤想象成是执行了下面的代码

var s1 = new String( "some text" )

var s2 = s1.substring( 2 );

s1 = null

var str = 'text';

str instanceof String; // false

instanceof 运算符用于测试构造函数的prototype 属性是否出现在对象的原型链的任何位置。

本身用于一个检测函数(Function ) or 对象 ( Object ) 的属性方法,为什么要去检测基本类型。

但是在查文档的时候看到一个好玩的东西。

所以说JS 是一门灵活的语言。。

instanceof 判断 Object 类型的陷阱

这里说明一下,用 instanceof 判断 Array 类型基本OK。

var arr = [1, 2, 3]

arr instanceof Array; // true

但是 instanceof 却不能安全的判断Object 类型, 因为 Array 构造函数是继承自 Object 对象的, 因此 在arr 变量上是可以访问到 Object 的 prototype 属性的。

var arr = [ 1, 2, 3 ]

arr instanceof Object; // true

看来 Object 是扩展了 arr 函数,所以根本没得判断在这个位置。

一个高效但危险的变量判断方法

实在太长,但也是一种不错的判断方法

function cstor(variable) {
if (variable === null || variable === undefined) {
    return 'Null or Undefined';
}
var cst = variable.constructor;
switch (cst) {
case Number:
return 'Number'
case String:
return 'String'
case Boolean:
return 'Boolean'
case Array:
return 'Array'
case Object:
return 'Object'
}
}

需要排除 null 和 undefined 的干扰

最后的一个全能方法

Object.prototype.toString.call()

https://www.cnblogs.com/onepixel/p/5126046.html

以上截止。