Number()和new Number()的区别以及一种简单实现
看JavaScript文档的时候注意到了这种用法 var n1 = Number(123); , 冒出的第一个疑问就是和 var n2 = new Number(123); 有什么区别呢?
首先用typeof做下探测, n1是number而n2是object, 他们的本质区别就是type不同.
那么有趣的问题来了, Number内部肯定知道是怎么调用的它. 假设在没有Number的情况下, 如果我要实现个类似的类应该怎么做呢?
最先想到的就是根据caller来区分, 但在实验的过程中发现两个问题:
- 全局调用的时候没有caller
- 就算知道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()的区别以及一种简单实现的更多相关文章
- JS由Number与new Number的区别引发的思考
在回答园子问题的时候发现了不少新东西,写下来分享一下 == 下面的图就是此篇的概览,另外文章的解释不包括ES6新增的Symbol,话说这货有包装类型,但是不能new... 基于JS是面向对象的,所以我 ...
- 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 ...
- [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 ...
- odd number、 even number
odd number 奇数 even number 偶数
- JavaScript Number() Vs new Number()
最近在优化一个页面时候.IDEA 提示我错误的使用了包装类.当时感觉很诧异. 随后.我上Stack Overflow上面查了一下,终于发现了问题所在. new Number('123') 与 Numb ...
- 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()用来检查 ...
- 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 如何在不将数字转换 ...
- js 转为整数之Number()、parseInt()、parseFloat()区别
一:Number() 如果是Boolean值,true和false值将分别被转换为1和0. 如果是数字值,只是简单的传入和返回. 如果是null值,返回0. 如果是undefined,返回NaN. 如 ...
- oracle number 和sqlserver numeric的区别
number如果不指定范围默认是可以输入所有位数的小数,numeric如果不指定小数默认是不允许输入小数
随机推荐
- Zabbix 单位换算
直接举一例子,然后再举一反三: 如图: 单位B 则基数为1024(倍数) 我性能参数为KB单位,我们则把单位转换成和我们计数器 保持一致的单位即可,一致后,zabbix 后面会自己准换成自己想要的显示 ...
- 一秒搞定mysql的远程登录
执行下面命令! mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'mypw' WITH GRANT OPTION ; ...
- dlib人脸关键点检测的模型分析与压缩
本文系原创,转载请注明出处~ 小喵的博客:https://www.miaoerduo.com 博客原文(排版更精美):https://www.miaoerduo.com/c/dlib人脸关键点检测的模 ...
- voip技术研究
voip:是一种通过ip现实电话通信的技术统称 sip:voip现在一般都采用sip协议 参考资料: android sip学习 问题: SipManager.newInstance(this)为nu ...
- Mac下jenkins用户权限配置错误,导致登录时提示:没有Overall/read权限
由于初次接触jenkins,于是在搭建好jenkins以后,想要对用户进行管理,于是乎开始在系统管理->configure Global Security里设置用户的权限. 在启用安全-> ...
- 微信小程序实现简易留言板
微信小程序现在很火,于是也就玩玩,做了一个简易的留言板,让大家看看,你们会说no picture you say a j8 a,好吧先上图. 样子就是的,功能一目了然,下面我们就贴实现的代码,首先是H ...
- Mac 下 android/iOS https抓包
一.Charles简介 Charles,是用Java开发的,所以跨平台,不仅可以在Mac上使用,Linux以及Window下都是可以使用的,当然需要安装JDK,才能运行,但目前是收费的. 二.下载 官 ...
- 【三分模板】洛谷P3382三分模板
题目描述 如题,给出一个N次函数,保证在范围[l,r]内存在一点x,使得[l,x]上单调增,[x,r]上单调减.试求出x的值. 输入输出格式 输入格式: 第一行一次包含一个正整数N和两个实数l.r,含 ...
- JSP动态产生的代码,点击显示确认操作,根据操作跳转并传值。
假如有如下一段代码产生了多个选项我们改如何获得点击删除一项中的值? <%List<Theme> themelist=(List<Theme>)request.getAtt ...
- Kubernetes 架构(上)- 每天5分钟玩转 Docker 容器技术(120)
Kubernetes Cluster 由 Master 和 Node 组成,节点上运行着若干 Kubernetes 服务. Master 节点 Master 是 Kubernetes Cluster ...