为什么JS中数值类型已经可以使用Number方法,还要引入Number对象概念?

JavaScript011

为什么JS中数值类型已经可以使用Number方法,还要引入Number对象概念?,第1张

JavaScript中,数值类型有两种表示方式:直接量和Number对象。这两种表示方式在大多数情况下是等价的,但是它们有一些重要的区别。

直接量(也称为原始值)表示一个数值常量,它直接写在代码中,例如10或者3.14。直接量是不可变的,它们是原始类型的值,不能调用方法,只能进行基本的运算。

Number对象表示一个数值,但是它是一个对象,而不是原始类型的值。Number对象可以调用方法来执行更高级的操作,比如转换为字符串、比较大小等。但是,由于Number对象是可变的,所以它的性能要比直接量差一些。

所以,通常来说,我们应该优先使用直接量来表示数值,只有在需要使用Number对象的方法时才使用Number对象。

对于上面的例子,n1和n2两者都可以调用toString()方法来将数值转换为字符串,但是n2是一个Number对象,所以它可以调用更多的方法。例如,使用Number.isInteger()方法检查一个数值是否为整数时,n1是直接量,所以它可以直接传入`Number

另外,由于Number.isInteger()方法是Number对象的一个静态方法,而不是实例方法,所以它无法直接在Number对象实例上调用。例如,在上面的例子中,Number.isInteger(n1)返回true,因为n1是一个直接量,它可以直接传入Number.isInteger()方法;而Number.isInteger(n2)返回false,因为n2是一个Number对象实例,而不是直接量,它不能直接传入Number.isInteger()方法。

总之,直接量和Number对象两者都可以表示数值,但是它们有一些重要的区别,应该根据实际情况来选择使用哪种方式。通常来说,我们应该优先使用直接量来表示数值,只有在需要使用Number对象的方法时才使用Number对象。

Number可以把任何类型的数据转换为数值,parseInt和parseFloat只能把字符串或数值转换为数值;

Number把空字符串转换为0,而parseInt和parseFloat则是转换为NaN;

Number和parseInt会把有效的十六进制格式字符串(例如"0xf")转换为十进制数,而parseFloat会转为0;

Number和parseFloat都会把前面带0的数字字符串(如"0123")转换为十进制的整数或浮点数,而parseInt则按八进制数来转换(除非数字超出八进制的范围,如089);

Number和parseFloat会有效解析浮点数(比如"123.45mn"转为123.45),而parseInt只提取数字字符串中的整数部分(比如"123.45mn"转为123);

parseInt含有第二个参数,用来规定数字转换的进制数(从2到36),比如parseInt("10",12)会按十二进制来解析10,结果就是十进制的12。而Number和parseFloat则没有这个功能。

下面有具体的注释:

Number.prototype.times = function(f,context){ //向Number类中添加一个times方法,这个方法可传入两个参数

var n = Number(this) //这里的变量n与下面的n并不是一个变量,这个变量属性Number类下times方法中的局部变量。它只在这个方法中起作用。

for (var i = 0 i < n i++) {

f.call(context,i)

//f.apply(context,[i,i])

}

}

var n = 4 //在JS中,一个数字也是一个对象,它会有自己的方法,由于上面的代码为数字类添加了一个times方法,所以这个数字便拥有了times方法,可以直接调用

n.times(function(n,l){//这里,就调用 了刚刚为Number类增加的times方法,传入的值只有一个,这个值是一个匿名函数

debugger //在调试模式下,JS运行到这里会暂停,也就是一个断点

console.log(n + " hello " + l ) //在控制台中输出文字

})

两个n并不是一个,它们完全不是同一个变量,可以说,它们之间没什么直接的关系,完全可以改名

比如:

var num = 158

num.times(function(){})

其实,var n = Number(this) 这里面的this,就是指158这个数字对象。

然后将这个对象再Number(),就是将对象转换为数字。

————

这段代码里,涉及到了几个知识点,你需要了解:

JS 变量作用域;

JS类;

JS对象;

JS prototype;

JS 类继承(JS call())

而你当前所的疑惑的,就是变量作用域,如果你不太好理解,可以看下面的代码,与上面的代码是一样的,其中我只改了后面的变量名:

Number.prototype.times = function(f,context){ //向Number类中添加一个times方法,这个方法可传入两个参数

var n = Number(this) //这里的变量n与下面的n并不是一个变量,这个变量属性Number类下times方法中的局部变量。它只在这个方法中起作用。

for (var i = 0 i < n i++) {

f.call(context,i)

//f.apply(context,[i,i])

}

}

var otherN = 4 //在JS中,一个数字也是一个对象,它会有自己的方法,由于上面的代码为数字类添加了一个times方法,所以这个数字便拥有了times方法,可以直接调用

otherN.times(function(otherN,l){//这里,就调用 了刚刚为Number类增加的times方法,传入的值只有一个,这个值是一个匿名函数

debugger //在调试模式下,JS运行到这里会暂停,也就是一个断点

console.log(otherN + " hello " + l ) //在控制台中输出文字

})