看JavaScript文档的时候注意到了这种用法 var n1 = Number(123); , 冒出的第一个疑问就是和 var n2 = new Number(123); 有什么区别呢?

首先用typeof做下探测, n1是number而n2是object, 他们的本质区别就是type不同.

那么有趣的问题来了, Number内部肯定知道是怎么调用的它. 假设在没有Number的情况下, 如果我要实现个类似的类应该怎么做呢?

最先想到的就是根据caller来区分, 但在实验的过程中发现两个问题:

  1. 全局调用的时候没有caller
  2. 就算知道caller也无法区分它是function调用还是构造对象

所以caller这条路就走不通了, 既然需要在运行期区分, 那么该"真爱" this 登场了. this指向当前构造的对象, 我就可以区分是function调用还是构造对象了.

我的新轮子命名为WNumber, 思路理清楚后就剩施工了. 为了更接近Number的行为, 在开工前先用测试数据探测下:

console.log(Number(123));      //
console.log(Number(+123)); //
console.log(Number(-123)); //-123
console.log(Number("123")); //
console.log(Number("+123")); //
console.log(Number("-123")); //-123
console.log(Number("abc123")); //NaN
console.log(Number(NaN)); //NaN console.log(new Number(123)); //save as above except type
console.log(new Number(+123));
console.log(new Number(-123));
console.log(new Number("123"));
console.log(new Number("+123"));
console.log(new Number("-123"));
console.log(new Number("abc123"));
console.log(new Number(NaN));

WNumber的源码最后贴出来, 先说下遇到的问题和处理思路. 在测试过程发现 123 == new Number('123') 是返回true的, 但我们的 123 == new WNumber('123') 却返回false, 难道浏览器不给WNumber国民待遇?

首先浏览器是不可能把123 auto-box成Number对象的, 因为两个对象==是false的, 所以肯定是把Number对象auto-unbox成原始type(值type). 查了一下文档对象刚好有个valueOf()方法用来返回这个对象代表的原始值. (后来测试过程中发现valueOf()或toString()实现任一一个方法都能让浏览器返回true)

下面是实现WNumber的源码:

    function WNumber(i){

        var primitiveValue = 0;

        if(typeof i === "number"){
primitiveValue = i;
}else{
var regR = /^([\+\-]?)([0-9]+)$/.exec(i);//正则表达式抓取正负符号和数字的文本值
if(regR !== null){
var nstr = regR[2];//数字的文本值,相当于Java的group(2)
var nstrlen = nstr.length;
var nResult = arguments.callee(0);//callee就是本function
for(idx in nstr){
//通过计算ASCII码的差值转换成数字, 见后记
nResult += (nstr[idx].charCodeAt(0) - "0".charCodeAt(0)) * Math.pow(10, nstrlen - idx -1);
}
if(regR[1] === "-"){//判断正负值
primitiveValue = -nResult;
}else{
primitiveValue = nResult;
} }else{
primitiveValue = NaN;
}
} if(this instanceof WNumber){
//construct object
this.valueOf = function(){
return primitiveValue;
} this.toString = function(){
return primitiveValue + '';
}
return this;
}else{
//invoke as function
return primitiveValue;
}
}

后记: string快速转换成number的方法是 "123" * 1 = 123 , 但这是语法糖, 实际上是 Number("123") * 1 , 所以我选择计算ASCII码的差值.

Number()和new Number()的区别以及一种简单实现的更多相关文章

  1. JS由Number与new Number的区别引发的思考

    在回答园子问题的时候发现了不少新东西,写下来分享一下 == 下面的图就是此篇的概览,另外文章的解释不包括ES6新增的Symbol,话说这货有包装类型,但是不能new... 基于JS是面向对象的,所以我 ...

  2. Find n‘th number in a number system with only 3 and 4

    这是在看geeksforgeeks时看到的一道题,挺不错的,题目是 Given a number system with only 3 and 4. Find the nth number in th ...

  3. [Locked] Strobogrammatic Number & Strobogrammatic Number II & Strobogrammatic Number III

    Strobogrammatic Number A strobogrammatic number is a number that looks the same when rotated 180 deg ...

  4. odd number、 even number

    odd number 奇数 even number 偶数

  5. JavaScript Number() Vs new Number()

    最近在优化一个页面时候.IDEA 提示我错误的使用了包装类.当时感觉很诧异. 随后.我上Stack Overflow上面查了一下,终于发现了问题所在. new Number('123') 与 Numb ...

  6. es6 Number.isFinite()、Number.isNaN()、Number.isInteger()、Math.trunc()、Math.sign()、Math.cbrt()、Math.fround()、Math.hypot()、Math 对数方法

    ES6在Number对象上,新提供了Number.isFinite()和Number.isNaN()两个方法,用来检查Infinite和NaN这两个特殊值. Number.isFinite()用来检查 ...

  7. how to convert a number to a number array in javascript without convert number to a string

    how to convert a number to a number array in javascript without convert number to a string 如何在不将数字转换 ...

  8. js 转为整数之Number()、parseInt()、parseFloat()区别

    一:Number() 如果是Boolean值,true和false值将分别被转换为1和0. 如果是数字值,只是简单的传入和返回. 如果是null值,返回0. 如果是undefined,返回NaN. 如 ...

  9. oracle number 和sqlserver numeric的区别

    number如果不指定范围默认是可以输入所有位数的小数,numeric如果不指定小数默认是不允许输入小数

随机推荐

  1. Python中将函数作为另一个函数的参数传入并调用

    在Python中,函数本身也是对象,所以可以将函数作为参数传入另一函数并进行调用 在旧版本中,可以使用apply(function, *args, **kwargs)进行调用,但是在新版本中已经移除, ...

  2. 阻止form空表单提交----JavaScript

    网上看到很不错的阻止form空表单提交 第一种方法 <div class="warp"> <h2>登录到pfan空间</h2> <p> ...

  3. svn conflict 冲突解决

    1. 同一处修改文件冲突 开发人员都知道代码管理工具是开发中一个必不可少的工具,这里也不废话详细介绍了.不管你个人喜欢git还是svn还是其他,但还有一大部分公司在使用svn做代码管理工具.这里详细介 ...

  4. ES6解构之复杂数据

    今天在写代码的是否,碰到如下的数据,我要取值 fvkey,fn,url. { , , "fl":Object{...}, , "ip":"106.39 ...

  5. 常见的DBCP连接池配置

    项目中使用mybatis出现一个问题,项目刚启动时,查询项目列表是ok的,过上一段时间之后,再次查询项目列表,查询失败,初步判断是因为mysql的连接问题,最后查阅资料,发现是连接池中的连接失效,导致 ...

  6. java.io与网络通信

    文件IO java.io.File是用于操作文件或目录的类: File file = new File("hello.txt"); 实例化File时不关心路径的目标并不会去读取文件 ...

  7. python 最基本的的单例模型的实现及应用

    在我们python开发过程很多 ,在很多地方都会用到单例模式,确保数据的唯一性,最简单的单例模式,我们可以模块导入的方式实现,因为导入文件,无论import多少次  都只导入一次模块. 方法一:装饰器 ...

  8. 共60课:Python基础教程

    简介: 你会看到一堆下载链接.我们就选"Python 2.7.5 Windows Installer",如果是64位系统的同学选下面那个"Python 2.7.5 Win ...

  9. Windows下Java环境变量配置

    新建: JAVA_HOMEC:\Program Files\Java\jdk1.8.0_25 新建或添加到开头: PATH %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin; C ...

  10. HDU2825 Wireless Password

    Description Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless ne ...