JavaScript数据类型检测(一次性讲清楚)

(1) 四种常见方案

  • typeof
  • instanceof
  • constructor
  • Object.prototype.toString.call(value)

(2) typeof

  • 原理
    typeof在计算机底层根据js数据类型的二进制的值进行检测的。在JavaScript中,用32个二进制位来标识JavaScript中的值,其中低三位来表示值的类型。000表示对象,010表示浮点数,100表示字符串,110表示布尔值,001表示整数,-2^30表示undefined,全0表示null

  • 类型判断结果

    valuetypeof value
    数值/NaN/Infinity‘number’
    字符串‘string’
    true/false‘boolean’
    undefined‘undefined’
    null‘object’
    大整数‘bigint’
    Symbol类型‘symbol’
    函数‘function’
    非函数对象‘object’
  • 总结
    从上面表格可以发现typeof能较好地判断基本数据类型(null除外);而对于引用数据类型,则只能判断function类型的数据。

  • 问题1:typeof null 检测出来的结果为什么是object
    typeof是根据二进制值来判断数据类型的,null的二进制值是全0,而object类型的二进制值都是000 开头的,所以typeof检测null时也被检测成object(可以理解为这是JavaScript历史遗留下来的bug)

  • 问题2:为什么typeof判断函数可以判断出是function类型(而不是object)?
    虽然在JavaScript中函数也是对象,但是在进行typeof判断时候,如果遇到函数时会自动调用call方法来判断。

(3) instanceof

  • 原理
    只要当前类在被检测的实例的原型链上,结果都是true

      console.log([] instanceof Array)//true
      console.log([] instanceof RegExp)//false
      console.log([] instanceof Object)//也是true
    

    最后一行可能有人觉得奇怪,后续我会花专门章节分析原型链相关知识。在这大致解释起来就是空数组[]这个被检测的实例的原型链上有ArrayObject

  • 一些弊端
    可以肆意修改原型的指向,会导致检测出来的值可能不准确

    function Fn(){
       this.x=10;
     }
     Fn.prototype=Object.create(Array.prototype);
     let f=new Fn();
     console.log(f instance Array)//true
    

    并且instanceof不能检测基本数据类型。

  • 手写instanceof

    function myInstance(example,classFunc){
      // 实例.__proto__===类.prototype
      if(typeof example !=="object" || example ===null){
          return false;
      }
      //获取参数的原型对象
      let proto=Object.getPrototypeOf(example);
      //这里没有用 example.__proto__,因为IE浏览器不兼容
      while(true){
        if(proto===null){
          return false;
        }
        if(proto===classFunc.prototype){
          return  true;
        }
         proto=Object.getPrototypeOf(proto)
      }
    }
    

(4) constructor

  • 用起来比instanceof似乎好一些(也支持基本数据类型)
       let arr=[];
       console.log(arr.constructor===Array);//true
       console.log(arr.constructor===RegExp);//false
       console.log(arr.constructor===Object);//false
       let n=1;
       console.log(n.constructor===Number);//true
    
  • constructor可以随意改变,所以也不准确
      Number.prototype.constructor="AA";
      let n=1;
      console.log(n.constructor===Number);//false
    

(5) Object.prototype.toString.call(value)

  • Object.prototype.toString不是转换为字符串,是返回当前实体所属类的信息,call是改变this指向。
  • 可以检测所有类型的值
     [object Number]
     [object String]
     [object Boolean]
     [object Null]
     [object Undefined]
     [object Symbol]
     [object Object]
     [object Array]
     ...等等
    

(6) 封装一个检测数据类型的方法

  • 思路
    基本数据类型用typeof判断,引用数据类型用Object.prototype.toString.call判断
  • 代码
    function getType(obj){
      //简约undefined和null
      if (obj==null){
        return obj+"";
      }
      if (typeof obj =='object' || typeof obj =='function'){
        let typeStr = Object.prototype.toString.call(obj)
        // 解析[object String]
        typeStr = typeStr.split(' ')[1]
        type = typeStr.substring(0, typeStr.length - 1)
         return  type.toLowerCase();
      }
      return  typeof obj;
    }
    
<think>好的,用户让我讲讲GET方法的使用,首先我需要明确他们可能的背景。可能是个刚学Web开发的,或者对HTTP方法不太熟悉的新手。GET是HTTP中最常用的方法之一,但具体细节和注意事项他们可能不太清楚。 首先,我应该从基本定义开始,解释GET是什么,用途是什么。GET主要用于请求数据,应该强调它是幂等的,而且参数在URL里可见,这样用户能明白它的基本特性。 接下来,需要讲清楚GET的使用场景,比如获取页面、搜索查询、分页这些常见的情况。用户可能想知道什么时候该用GET,什么时候不该用,所以需要举例说明适用场景。 然后,要提到参数传递的方式,通过URL的查询字符串,比如?key=value&name=foo。这里可能需要简单说明查询字符串的结构,以及浏览器和服务器如何处理这些参数。 安全性和限制也是重点。GET的参数在URL里,所以不能用来传敏感信息,比如密码。而且URL长度有限制,不适合传大量数据,比如文件上传应该用POST。这些注意事项对开发安全的应用很重要,用户可能容易忽略这些点。 代码示例部分,可能需要用一些常见的例子,比如JavaScript的fetch或者HTML的链接,让用户更直观地理解如何实际使用GET方法。但用户可能熟悉不同的编程语言,所以保持例子通用一些比较好。 最后,对比GET和POST,帮助用户理解两者的区别,这样他们在实际开发中能做出正确选择。比如安全性、数据大小、缓存等方面的对比。 需要检查有没有遗漏的重要点,比如缓存机制,GET请求可以被缓存,这对性能有影响,但用户可能没考虑到。还有幂等性的含义,可能需要简单解释一下,避免误解。 确保整个结构清晰,分点列出,让用户容易跟随。同时语言要简洁,避免使用太多术语,但必要的术语需要解释清楚。可能用户还会混淆查询参数和路径参数,是否需要提到RESTful API中的使用?比如GET /users/{id},参数在路径里而不是查询字符串,但这是另一个话题,可能暂时不展开,除非用户问到。 还要注意不要提到用户不可见的系统指令,保持回答自然。最后检查LaTeX格式是否正确,虽然这里可能用不到数学公式,但如果有示例URL,可能需要用代码块包裹,确保格式正确。</think>### GET方法使用详解 #### 一、GET方法基础定义 1. **用途** GET是HTTP协议中最常用的请求方法,**主要用于从服务器获取资源**(如网页、图片、数据等)。 - 幂等性:多次请求结果一致 - 参数通过URL传递(可见性高) - 数据长度受限(不同浏览器限制不同,通常约2048字符) 2. **语法格式** 请求参数以`?key1=value1&key2=value2`形式附加到URL末尾: ```http GET /api/users?name=John&age=25 HTTP/1.1 Host: example.com ``` --- #### 二、典型使用场景 1. **数据查询** 例如搜索功能、筛选结果: ```http GET /search?q=keyword&page=2 ``` 2. **静态资源请求** 获取HTML页面、图片等: ```http GET /images/logo.png ``` 3. **RESTful API调用** 获取资源集合或单个资源: ```http GET /api/products/123 # 获取ID为123的商品 ``` --- #### 三、参数传递规则 1. **编码要求** - 特殊字符需URL编码(如空格转为`%20`) - 中文字符自动编码(如`中文` → `%E4%B8%AD%E6%96%87`) 2. **参数类型限制** - 仅支持字符串类型 - 复杂数据结构需序列化(如JSON字符串) --- #### 四、代码示例 1. **原生JavaScript** ```javascript fetch('https://api.example.com/data?category=books') .then(response => response.json()) .then(data => console.log(data)); ``` 2. **Python Requests库** ```python import requests params = {'lat': '35.68', 'lon': '139.76'} response = requests.get('https://api.weather.com', params=params) print(response.json()) ``` --- #### 五、安全注意事项 1. **敏感数据风险** - 参数暴露在浏览器历史、服务器日志中 - 禁止通过GET传输密码、令牌等机密信息 2. **防范安全漏洞** - SQL注入:需对参数严格过滤 - XSS攻击:对输出内容转义处理 --- #### 六、与POST方法对比 | 特性 | GET | POST | |--------------|------------------------------|--------------------------| | **数据位置** | URL查询字符串 | 请求体(Body) | | **安全性** | 低(明文可见) | 较高(不可见) | | **数据长度** | 受URL长度限制 | 无限制 | | **缓存** | 可被浏览器/代理缓存 | 不可缓存 | | **幂等性** | 幂等(多次请求结果一致) | 非幂等 | --- #### 七、最佳实践建议 1. 仅用GET请求**读取操作**,修改数据用POST/PUT/DELETE 2. 重要参数超过1000字符时改用POST 3. 对用户输入参数做合法性校验 4. 敏感操作需配合CSRF Token防护 通过合理使用GET方法,可以构建更高效、安全的Web应用。实际开发中需结合具体场景选择HTTP方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

太阳与星辰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值