资讯专栏INFORMATION COLUMN

利用Object.prototype.toString.call()来进行类型检验

JackJiang / 594人阅读

摘要:会将数组中的每个元素一个个传入给。参考链接与的区别二进行类型检验首先来看一个问题,用来检验类型有什么缺点呢答案是无法准确地检验对象类型。比较好的方式就是用来进行检验。判断是否是对象类型注意使用是不能得到类型的。

一、apply与call的区别

相同点:“可以让一个对象调用另一个对象的方法”
不同点:

apply最多只能传入两个参数,第一个为对象,第二个为数组

call能传入多个参数,第一个为对象,其后为n个参数列表

实际上,apply和call实现的功能是一样的,只是传入的参数不同而已。

示例:

</>复制代码

  1. function add(a,b){
  2. return a+b;
  3. }
  4. function sub(a,b){
  5. return a-b;
  6. }
  7. var a1 = add.apply(sub,[4,2]);  //sub调用add的方法
  8. var a2 = sub.apply(add,[4,2]);
  9. alert(a1); //6
  10. alert(a2); //2
  11. /*call的用法*/
  12. var a1 = add.call(sub,4,2);
apply的一些使用技巧

配合Math.max()计算数组最大值

因为Math.max()不支持数组的方式,只能Math.max(a,b,c....)
根据apply的特点来实现这一功能,Math.max.apply(null,[1,2,3]),因为没有新的对象调用Math的max方法,所以只是传入null来利用apply的特性帮助进行计算而已。

apply会将数组中的每个元素一个个传入给Math.max()。也就相当于Math.max.call(null,1,2,3)

同理可以用Math.min.apply(null,[1,2,3])计算数组最小值

</>复制代码

  1. 注意:在ES6中就更加简单了,Math.max.apply(...[1,2,3])

配合Array.prototype.push实现两个数组合并

数组的push方法是不能push数组的,但是可以同时push多个元素,因此可以利用apply的特性

</>复制代码

  1. var a = [1,2,3];
  2. var b = [4,5,6];
  3. Array.prototype.push.apply(a,b);//apply会将为b中每一个元素执行一次push方法。返回值是push后数组a的长度

同样在ES6中只需要a.push(...b),就可以实现。

</>复制代码

  1. 参考链接:
    apply()与call()的区别
二、Object.prototype.toString.call()进行类型检验

首先来看一个问题,用typeof来检验类型有什么缺点呢?

答案是typeof无法准确地检验对象类型。

</>复制代码

  1. typeof null //object
  2. typeof [] //object

比较好的方式就是用 Object.prototype.toString.call()来进行检验。

</>复制代码

  1. var a = {};
  2. var b = [];
  3. var c = 1;
  4. Object.prototype.toString.call(a);//[object,Object]
  5. Object.prototype.toString.call(b);//[object,Array]
  6. Object.prototype.toString.call(c);//[object,Number]
  7. //判断a是否是对象类型
  8. Object.prototype.toString.call(a) === "[object,Object]"

</>复制代码

  1. 注意:使用obj.toString()是不能得到类型的。
    原因:Array,Function等类型作为Object的实例,都重写的了toString方法。因此在调用时,是调用了重写后的方法,而不是原型链上的toString()方法

</>复制代码

  1. var arr=[1,2,3];
  2. console.log(Array.prototype.hasOwnProperty("toString"));//true
  3. console.log(arr.toString());//1,2,3
  4. delete Array.prototype.toString;//delete操作符可以删除实例属性
  5. console.log(Array.prototype.hasOwnProperty("toString"));//false
  6. console.log(arr.toString());//"[object Array]"

删除了重写的方法后,使用obj.toString()也就相当于调用原型链的方法了,即Object.prototype.toString.call()

</>复制代码

  1. 参考链接:

  2. 为什么用Object.prototype.toString.call(obj)检测对象类型?

  3. 深入理解Object.prototype.toString.call()

  4. 原文地址

三、封装成函数

可以通过以下方式封装成一个函数,语义更加清晰

</>复制代码

  1. export function typeOf (param) {
  2. return Object.prototype.toString.call(param).match(/s+(w+)/)[1] //正则匹配
  3. }

Vue中可以定义成全局函数

</>复制代码

  1. //main.js
  2. Vue.prototype.typeof = function (param) {
  3. return Object.prototype.toString.call(param).match(/s+(w+)/)[1]
  4. }
  5. // 组件中调用
  6. this.typeof([])//Array

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/108226.html

相关文章

  • JS数据类型检验

    摘要:如果此方法在自定义对象中未被覆盖,返回,其中是对象的类型那为什么会报错呢这是为什么呢,因为为构造函数,构造函数本身没有方法。依照原型链关系,构造函数的上游原型链是。所以,你调用本质上是调用,这里需要的参数类型是函数,所以会报错。 我们知道判断数据类型可以用typeof 定义一些数据 let num=1,str=str,bool=true,obj={},arr=[],sy=Symbol(...

    wuyumin 评论0 收藏0
  • JavaScript的数据类型及其检测

    摘要:值的比较只进行值的比较会进行数据类型的转换。只要在当前实例的原型链上,我们用其检测出来的结果都是。但检测与不一样,还可以处理基本数据类型的检测。 showImg(https://segmentfault.com/img/remote/1460000016733921); 一、JavaScript有几种类型的值? Javascript有两种数据类型,分别是基本数据类型和引用数据类型。其中...

    starsfun 评论0 收藏0
  • JavaScript的数据类型及其检测

    摘要:值的比较只进行值的比较会进行数据类型的转换。只要在当前实例的原型链上,我们用其检测出来的结果都是。但检测与不一样,还可以处理基本数据类型的检测。 showImg(https://segmentfault.com/img/remote/1460000016733921); 一、JavaScript有几种类型的值? Javascript有两种数据类型,分别是基本数据类型和引用数据类型。其中...

    dingding199389 评论0 收藏0
  • JavaScript的数据类型及其检测

    摘要:值的比较只进行值的比较会进行数据类型的转换。只要在当前实例的原型链上,我们用其检测出来的结果都是。但检测与不一样,还可以处理基本数据类型的检测。 showImg(https://segmentfault.com/img/remote/1460000016733921); 一、JavaScript有几种类型的值? Javascript有两种数据类型,分别是基本数据类型和引用数据类型。其中...

    Moxmi 评论0 收藏0

发表评论

0条评论

JackJiang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<