当前位置: 首页 >文章 > 让js中数据类型的所有方法都通用起来
收藏
分享

让js中数据类型的所有方法都通用起来

举报李游Leo李游Leo发布于 2020-05-011242阅读3点赞
js中两个比较接近的数据是数组和json...

数组可以拥有字符串的方法,字符串拥有数组的方法,而 json 同时拥有以上两种方法,是不是很神奇?其实我倒是喜欢管这种方法叫做「数据类型欺骗」。


首先说一下 js 中两个比较接近的数据,一个叫数组,一个叫 json。为什么先拿这两个讲呢?第一点,它俩都是一个“ 爹 ”,没错,都是Obj。再说一下他俩不一样的地方。


json没有 length ,准确的说是 json 的 length 是 undefined 。其实这只是这个对象的一个私有属性而已,因为没有这条私有属性,所以才是 undefined。而 Array.prototype 里面有 length 的方法,第二个数组可以用中括号取到对应的值也就是:


var a = [1,2,3];


a[0]//1


a[1]//2


中括号里面必须放数字,而这个特性其实 json 算是支持的。这就是给了咱们一个可乘之机。


ok,现在就用 json 伪造一个 [1,2,3] 的对象。


var a = {


'0':1


'1':2,


'2':2


} ;


在json中键值对中的key值只说明了不能用Number作为key值,ok既然如此,我可以用字符串的0,1,2.


这样如此做的话


a[0] //1


a[1] //2


似乎可以欺骗了系统了,当然还差最后一步也就是length,ok,我们直接赋予一个length。


var a = {


'0':1


'1':2,


'2':2,


length:3


} ;


这样的一个 a 其实在输出的时候和 [1,2,3] 就完全一样了。说白了,我们已经用一个 json,在不看内容的前提下其实可以完全骗过人的眼睛了。


到底能不能骗过系统的眼睛呢?在试验前我们先来讲一下对象的方法实现原理。其实所有的实例化对象的方法的函数 this 都是指向,你要操作的数据最后在 return 出 this。


咱们借助这个道理来试一试 用这个伪装的 json 能不能用数组的方法。首先,咱们先试试slice。


a.slice()//报错 没有该方法


[].slice.call(a) // 1,2,3 成功的骗过了浏览器


我们在深入一点试试。


Array.prototype.slice.call(a,1)// 2,3 确实截取到了。


如果这个 json 对象没有 length 的属性的时候,则会返回一个空数组,说明数组的 length 在这个方法中是会用到的。而咱们的 json,有了和数组一样的所有东西后,在变成这个方法的 this 之后,其实也可以骗过浏览器来执行数组的方法。


当然咱们再来一个比较稍微高难度的例子吧,数组有一堆属于自己的循环,例如:find 、 forEach 、findIndex咱们就试验最后一个吧。


[].findIndex.call(a,(function(e,index){


console.log(e);1,2,3


console.log(index); 0,1,2


}));


一点问题都没有,其实实测之后发现,数组的大部分方法都可以使用,这也就是说明了 json 完全也可以使用数组的方法,不过 json 要使用的话,还需要 key 值和 length 符合象数组一样,不过似乎也没啥意义了。当然 json 可不可以用字符串的方法呢?


var a = '123';



var a = {


'0':'1'


'1':'2',


'2':'2',


length:3


} ;


似乎在输出的时候没有什么明显的差异,他们的 a[0] 都是1,length也都是3。ok,让我们试试


'.substring.call(a)//'[object object]'


可以使用没有报错,也就是说 substring 认这个东西了。但是,内部他到内部就暴露了真实的自己他是一个对象,解析出来的 this 就是 obj 。最后也会 return 出这个东西来。当然你会说,字符串也有 new String 如果把这个放进去 会出现问题么?来,带着疑问我们来看看。


var a = new String('123');


''.substring.call(a) //'123';


而我试验了几个方法之后发现虽然没报错,但是,输出都是字符串'[object object]'。人家字符串自己的对象却是一点都没事,这其实也深度反应了一个问题。字符串的对象虽然具有对象的引用,或者说是私有属性所有特性,但是和 array 和 obj 的对象还是有一些本质的差别。当然玩完了 json,咱们来试试 数组玩字符串的。


var a = [1,2,3];


''.substring.call(a,1)//,2,3;


没报错,而且数组也刷了一回字符串的 substring 方法,超级酷。但是截取值确有些不是我们想要的。是',2,3';


其实不难发现 是到了内部数组变成了 '1,2,3',从第一个开始截取 自然最后就出现了',2,3';


其实试验了几种方法之后,发现字符串对数组还是蛮友好的,大部分都是支持的,但是你的数组放进去之后,会自动转换成字符串带逗号的。就像[1,2,3]转化成'1,2,3';不过数组方法对字符串其实就没那么友好了,不过有些方法还是蛮好使的。例如:


[].slice.call('123',1)//['2','3'];


变成了一个数组的 ['2','3'] 也就是‘123’在进去后自动变成了 一个['1','2','3']在从第一位开始截取的话 就变成['2','3']了,似乎效果不错 因为省下了 split('') 步骤,不过它也是只能一个字母一个字母变成分割,变成数组。不过一些别的方法就没着么走运了,例如:


var a = '123';


[].push.call(a,'4')//报错


其实试验了大部分,发现可以用的确实不多,不过还是有一小部分可以使用。


总之,这个东西其实在实战中没有什么实际的意义,不过如果要说的话就是其实数组、字符串、json的方法部分是可以通用的。

0条评论
别默默看啦~登录/注册一起参与讨论吧~

暂无评论

请选择举报理由

违反法律法规

侵犯个人权益

有害网站环境

更多训练营>>

为你推荐 · 训练营(全勤打卡报名费全额返累计全额返用户133,637人)

电商海报设计训练营
距离开班仅剩9天66人已报名
【5月】零基础手绘插画训练营
距离开班仅剩9天55人已报名
【5月】零基础动态表情包创作训练营
距离开班仅剩26天15人已报名
特惠
充值
7折购
今日还在继续学习的你,太棒了!
7
折扣券可用于
年费无限VIP
立 即
使 用
此活动优惠不可与其他活动叠加使用
有效期:000000
消息
登录即可查看消息记录
建议
意见
官方
客服
在线咨询客服热线

您可以与在线客服进行沟通获得帮助

工作日:9:00~22:00节假日:9:00~18:00

联系在线客服

您可以电话联系客服进行沟通获得帮助

工作日:9:30~18:30

400-862-9191
虎课
积分
免费学习89000+个教程!
配套素材、源文件一键下载!
昨日学员已学习了27,078
并提交了210份作业!
登录后立即学习!
loading
微信扫码关注即可登录
您需要同意协议才可以进行登录
登录虎课网,每天免费学课程全站 89000+ 视频会员教程 | 每日可免费学 1
为确保账户信息安全
请先进行真实姓名验证后进行充值付款
立即验证