看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. Robot Framework学习笔记(十)------Selenium2Library库

    一.安装selenium2library库 如果已经安装了pip,则使用管理员模式打开windows命令行,输入pip install robotframework-selenium2library, ...

  2. Nginx集群之WCF分布式消息队列

    目录 1       大概思路... 1 2       Nginx集群之WCF分布式消息队列... 1 3       MSMQ消息队列... 2 4       编写WCF服务.客户端程序... ...

  3. js 类数组arguments详解

    arguments并不是一个真正的数组,而是一个"类似数组(array-like)"的对象: 就像下面的这段输出,就是典型的类数组对象: [, , callee: ƒ, Symbo ...

  4. File API文件操作之FileReader二

    上一篇说了FileAPI中FileReader的readAsText,这里继续上文,说说另外一个API readAsDataURL. 这个接口是将File或者Blob读成base64格式的字符串,然后 ...

  5. 机器学习小记——KNN(K近邻) ^_^ (一)

    为了让绝大多数人都可以看懂,所以我就用简单的话语来讲解机器学习每一个算法 第一次写ML的博文,所以可能会有些地方出错,欢迎各位大佬提出意见或错误 祝大家开心进步每一天- 博文代码全部为python 简 ...

  6. TPFrame框架之robot模块的基本使用

    经过几天的努力,基本功能版已经完成,有待大家验证... robot插件主要的功能是帮助我们写部分代码的基本,目前阶段已经实现后台curd数据管理的基本操作,更多功能待续... 1.首先下载robot插 ...

  7. Android之Bmob移动后端云服务器

    源码下载:http://download.csdn.net/download/jjhahage/10034519 PS:一般情况下,我们在写android程序的时候,想要实现登录注册功能,可以选择自己 ...

  8. 使用jemeter手工编写注册、登陆脚本 运用 fiddler (三)

    手工注册脚本的录制 我们可以发现  编写手工脚本 需要用到两个软件一起合作才能编写成功 工作亦是如此  养成良好的团队合作精神 是必不可少的 现在我们来看手工编写注册脚本 第一步 :我们先进入网站首页 ...

  9. Spring mvc之 发邮件(qq.163...)

    一. 邮件开发涉及到的一些基本概念 1.1.邮件服务器和电子邮箱 要在Internet上提供电子邮件功能,必须有专门的电子邮件服务器.例如现在Internet很多提供邮件服务的厂商:sina.sohu ...

  10. 个人项目--“”小鱼企业级开发系统“”Svn地址分享

    由于精力有限,博主现在只维护这一个系统,会不时的更新代码提交. ""小鱼企业级开发系统""的Svn地址:http://code.taobao.org/svn/S ...