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

数组可以拥有字符串的方法,字符串拥有数组的方法,而 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的方法部分是可以通用的。

欢迎点击进入李游Leo老师的前端课堂
点击进入本站最全全栈课程《李游Leo - Web前端,从零基础到全栈工程师》带你用最快的时间一步月薪上万

原文地址:https://blog.51cto.com/7669561/2433322

时间: 2024-11-07 23:57:01

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

JS中setTimeout()的使用方法具体解释

1. SetTimeOut()              1.1 SetTimeOut()语法样例              1.2 用SetTimeOut()运行Function              1.3 SetTimeOut()语法样例              1.4 设定条件使SetTimeOut()停止              1.5 计分及秒的counter    2. ClearTimeout()    3.  Set Flag   10.1 setTimeout( )

60秒验证码倒计时js代码 js样式代码 方块上下左右随机移动(定时器) js中获取元素的方法 js中表单提交

60秒验证码倒计时js代码 <script type="text/javascript"> var countdown=60; function settime(val) { if (countdown == 0) { //removeAttribute() 方法删除指定的属性. disabled属性规定应该禁用 input 元素. val.removeAttribute("disabled"); val.value="免费获取验证码"

node.js中的url.parse方法使用说明

node.js中的url.parse方法使用说明 *方法说明:* 讲一个URL字符串转换成对象并返回 代码如下: url.parse(urlStr, [parseQueryString], [slashesDenoteHost]) 接收参数: urlStr                                       url字符串 parseQueryString                   为true时将使用查询模块分析查询字符串,默认为false slashesDeno

JS中数据类型、原始数据、内置对象、包装类型对象、typeof

JS中数据类型.内置对象.包装类型对象.typeof关系  https://segmentfault.com/a/1190000018275384 JavaScript 数据类型和数据结构   https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Data_structures 原始数据 https://developer.mozilla.org/zh-CN/docs/Glossary/Primitive 原文地址:https://www

JS中的对象和方法简单剖析

众所周知,在js中对象就是精髓,不理解对象就是不理解js. 那么什么事js中的对象呢? 在js中,几乎一切皆对象: Boolean ,String,Number可以是对象(或者说原生数据被认作对象): Dates ,Maths,Regexps,Arrays,Funcitons,当然Objects,这些都是对象: JS中,所有值,除了原生值,都是对象:这些原生值包括:strings,numbers('3.14'),true,false,null和undefined 对象是包含变量的变量,js变量可

JS中数据类型及原生对象简介

js是一种专门设计用来给网页增加交互性的编程语言,它的技术体系包含了一下几个方面: 1.JavaScript核心语言定义:包括数据类型,变量,常量,运算符,语句等. 2.原生对象和内置对象 3.浏览器对象BOM 4.文档对象类型DOM 5.事件处理模型 将js添加到文档中的方法有三种: 1.内嵌式 2.将js源文件通过<script>元素的src属性连接到XHTML文档中 3.脚本包含在XHTML事件处理属性中,例如onclick js的数据类型分为原始数据类型和引用数据类型: 一.原始数据类

JS中定义类的方法&lt;转&gt;

转载地址:http://blog.csdn.net/sdlfx/article/details/1842218 PS(个人理解): 1) 类通过prototype定义的成员(方法或属性),是每个类对象共有的,一般不用来定义成员属性,一个对象修改了属性值,所有对象均被修改: 2) 类拥有prototype属性,类对象没有: 3) 每次new类对象或直接调用类(以下工厂方法形式),都会把定义类(function)的语句执行一次(单例模式可以避免这个情况): 4) 类是function类型,类对象是o

js中三个默认方法call,applay,bind

这三个都是函数自带的方法(Function.prototype),这三个方法都能够改变函数内部 this的指向, call //call方法接收三个参数,第一个是this指向,第二个,三个是传递给函数的实参,可以是数字,字符串,数组等类型的数据类型都可以 function fn(n1,n2){ console.log(this); console.log(n1,n2) } fn.call();//=>this:window; let obj = {fn:fn}; fn.call(obj);//=

js中数据类型的理解

1.js中的基本数据类型:String.Number.Boolean.Null和Undefined,还有一种复杂数据类型Object. 2.对于Null和Undefined的不同,现在的JavaScript设计为Null表示'无'的对象,转为数值0:undefined未定义,转为数值NaN.其中NaN的数据类型为number,意为Not a Number;当两种不同的数据的类型相运算时则要注意一些细节,自己总结了一点: 所有和undefined有关的运算,返回的为NaN:  Null + 0 =