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如果不指定小数默认是不允许输入小数
随机推荐
- SQLServer 发布订阅(Replication)造成的Memroy压力(cmemthread等待)
深入了解下发布订阅: 数据复制:允许一个数据源向一个或多个目标数据库分发数据,只需要OLE DB 访问接口即可访问: 整个复制框架包含:复制组件,复制代理,复制类型: 复制组件: 发布服务器: ...
- Java数组的创建和初始化
我们说到数组,可能有的人就会比较害怕了,其实,数组只是把对象序列(很多个对象)或者基本类型序列(很多个基本类型)放在一起而已.数组是通过方括号下标操作符[]来定义和使用的.如果要定义,创建一个数组,只 ...
- [C#]如何访问及调用类中私有成员及方法
本文为原创文章.源代码为原创代码,如转载/复制,请在网页/代码处明显位置标明原文名称.作者及网址,谢谢! 开发工具:VS2017 语言:C# DotNet版本:.Net FrameWork 4.0及以 ...
- php require、require_once和include、include_once的区别
一.引入php文件路径的方法require '文件路径'; require ('文件路径');require_once '文件路径'; require_once ('文件路径');include 同 ...
- 加载进度圈,带遮罩层(jquery)
如图: Js下载地址:http://files.cnblogs.com/files/holdon521/cvi_busy_lib.js 如下使用实例: <script src="/st ...
- 个人项目--“”小鱼企业级开发系统“”Svn地址分享
由于精力有限,博主现在只维护这一个系统,会不时的更新代码提交. ""小鱼企业级开发系统""的Svn地址:http://code.taobao.org/svn/S ...
- 分享一个android静默安装,安装后重新启动app的方法
一:需求简介 之前boss提出一个需求,运行在广告机上的app,需要完成自动升级的功能,广告机是非触摸屏的,不能通过手动点击,所以app必须做到自动下载,自动安装升级,并且安装完成后,app还要继续运 ...
- Asp.net Mvc 与 Web Api生命周期对比
完整的生命周期比较复杂,对细节感兴趣的同学可购买老A的图书学习:传送门 本文只简单讲述路由注册.controller创建.action选择的3个主逻辑线,其他的内容大家可自己阅读相应的代码 先上二者单 ...
- metasploit配置windows外网木马
首先在命令端输入./ngrok tcp 2222然后会变成这样 msfvenom -p windows/meterpreter/reverse_tcp -e x86/shikata_ga_nai -i ...
- set排序(个人模版)
set排序: #include<stdio.h> #include<string.h> #include<iostream> #include<set> ...