zoukankan      html  css  js  c++  java
  • Javascript中的基本数据类型,如何判断数据类型,作用域链的理解

    第一部分:Javascript中的数据类型

    javascript中 基本数据类型有 五种, 数字 number 字符串 string  布尔 boolean  未定义 undefined 空值 null

    另外有引用数据类型三种: 对象 object   数组 array  函数 function

    在ES6中,新增了三种数据类型  Set Map 和 Symbol

    第二部分:如何判断一个数据的数据类型呢?

    方法一:使用typeof 方法

    示例表明,使用typeof 方法可以判断出 number, string, boolean, undefined, object, symbol, function这7种结果,二话不说 上代码

    typeof 1  // number
    
    typeof 'a' //  string
    
    typeof false // boolean
    
    typeof undefined  // undefined
    
    typeof [] // object
    
    typeof {} // object
    
    typeof null // object
    
    const a = function(){}
    
    typeof a // function 
    
    typeof new Set()  // object
    
    typeof new Map() // object
    
    typeof Symbol // function
    
    typeof Symbol() // symbol

    方法二: 利用instanceof 用来判断构造函数,注意 只有引用类型的数据才可以使用 instanceof 方法,

    基本类型中的 数字 字符串 布尔值 可以利用 new 方法生成对象 

    比如 new Number(1) 就是一个对象了,就可以使用instanceof 方法 

    new Number(1) instanceof Number // true
    
    new String('str') instanceof String  // true 
    
    new Boolean(false) instanceof Boolean // true
    
    [] instanceof Array // true
    
    {} instanceof Object // true
    
    console.log instanceof Function // true
    
    console.log instanceof Function // true

    new Map() instanceof Map // true

    new Set() instanceof Set() // true

    那么以此就可以编写一个判断数据类型的方法啦

    function getType(param) {
        if( arguments.length === 0 ) {
             return '请传入参数'
        }
    
        if(param === null) {
             return 'null'
       }
    
        const type = typeof param 
        
        if( type !== 'object') { // 基本类型数据或symbol或function
              return type
        } else { // 引用类型
           if(param instanceof  Array){
              return 'array'
           } else if(param instanceof Set ) {
               return 'set'
           } else if(param instanceof Map) {
               return 'map'
           } else if(param instanceof Object) {
    return 'object'
    } } }

    附上测试结果:

    getType(1) // number
    
    getType('a') // string
    
    getType(false) // boolean
    
    getType([]) // array
    
    getType(null) // null
    
    getType(undefined) // undefined
    
    getType({}) // object
    
    getType(new Set()) // set
    
    getType(new Map())  // map
    
    getType(Symbol())  // symbol
    
    getType(Symbol) // function
    
    getType(console.log)  // function

    3.下面来讲讲 数据类型及其对应的构造函数

    在Javascript的数据类型中,除了 null ,undefined其他都有自己的构造函数

    比如 数字的构造函数 Number, 字符串构造函数 String, 布尔 Boolean   , 对象 Object, 函数 Function , Set()    Set, Map()  Map

    在基本类型中  可以使用 Number(1)  === 1 , String('a') === 'a',  Boolean(false) === false 

    而 new Number(1) 会得到一个对象,这个对象只有一个属性__proto__ 这个属性指向构造函数 Number 

    const num = new Number(1) 
    
    typeof num // 'object'
    
    typeof Number(1) //  number
    
    num.__proto__ === Number.prototype
    
    // Number.ptototype 下有多个方法 valueOf, toString,toFixed等,实际上对数字调用这些方法其实是调用Number.prototype上的方法
    
    num.toString() //  1
    
    Number(1) === 1
    
    Number(1) === new Number(1)  // false
     
    Number(1) == new Number(1)  // true
    
    1.toSting()  // 该方法会报错,因为JS无法分别.是小数点还是操作符
    
    正确做法是 const a = 1, a.toString()
    
    或者1['toString']()
    
    或者(1).toString()
     

    字符串和 布尔中道理也是一样的

    const  bol = new Boolean(false) 
    
    console.loog(bol) // Boolean{false}
    
    typeof bol // 'object'
    
    typeof Boolean(false) // 'boolean'
    
    Boolean(false) === false // true
    
    Boolean(false) === new Boolean(false) // false
    
    Boolean(false) == new Boolean(false) // true
    
    bol上同样有一个__proto__属性,指向Boolean.prototype,上面有valueOf, toString,constructor三个属性

    字符串当中

    const str = new String('str')
    
    console.log(str) // String{0: 's', 1: 't', 2: 'r'}
    
    String('str') === 'str' // true
    
    String('str') === str // false 
    
    String('str') ==  str // true
    
    str[0] === String('str')[0]
    
    str实际上是一个对象,该对象中有三个属性,还有长度属性,
    
    str.__proto__ === String.prototype 
    
    String('str').__proto__ === String.prototype

    第三部分:接下来再谈原型和原型链,就简单地多啦

    在 Javascript中,除了null,和 undefined这两个特殊的值,其他的一切都可以看做是实例对象,只是数字,字符串,布尔,symbol这样的一般不称他们为对象,

    除了null, undefined以外,所有的值都有自己的隐式原型属性__proto__,该属性指向这个值得构造函数的prototype

    看代码

    const num = 1
    
    const str = 'a'
    
    const bol = false
    
    const obj = {}
    
    const arr = []
    
    const sym = new Symbol()
    
    const set = new Set()
    
    const map = new Map()
    
    const fun = function() {}
    
    num.__proto__  ===  Number.prototype // true
    
    str.__proto__ === String.prototype // true
    
    bol.__proto__ == Boolean.prototype // true
    
    obj.__proto__ == Object.prototype // true
    
    arr.__proto__ === Array.prototype // true

    sym.__proto__ === Symbol.prototype // true map.__proto__ === Map.prototype // true set.__proto__ === Set.prototype // true fun.__proto__ === Function.prototype // true

    也就是说,任意一个数字,字符串,布尔,数组,对象,函数,set, map, symbol,都有一个__proto__属性,指向他们各自对应的构造函数

    那么 构造函数的__proto__属性会指向哪里呢?

    Number.__proto__ === Function.prototype
    
    Boolean.__proto__ === Function.prototype
    
    String.__proto__ === Function.prototype
    
    Array.__proto__ === Function.prototype
    
    Map.__proto__ === Function.prototype
    
    Set.__proto__ === Function.prototype
    
    Symbol.__proto__ === Function.prototype
    
    // 也就是说所有构造函数的原型,最终指向Function的显式原型对象
    
    那么Function.__proto__ 会指向谁呢,
    因为Function本事也属于构造函数,他的隐式原型,当然指向自身的显示原型对象
    
    Function.__proto__ === Function.prototype

    最后来讲一个特殊的,对象的__proto__属性,

    普通实例对象的__proto__属性,指向他的构造函数的prototype

    const obj = {}
    
    实际上相当于
    
    const obj = new Object()
    
    那么
    
    obj.__proto__ === Object.prototype
    
    最终问题来了,构造函数的显式原型对象,本身也是一个对象,他的__proto__会指向哪里呢?
    
    结果是
    
    除了Object构造函数以外,任意构造函数的显式原型属性的__proto__,都指向Object.prototype
    
    也就是说
    Array.prototype.__proto__ === Object.prototype
    
    Number.prototype.__proto__ === Object.prototype
    
    所有其他数据Boolean, Set, Map, Symbol, Promise等类型同理
    
    特殊的
    Function.prototype.__proto__ === Object.prototype
    
    而原型链的顶端:
    
    Object.prototype.__proto__ ===  null
    
    因为对象的显式原型对象也是一个对象,也该指向Object.prototype,
    单位了防止死循环,就把Object.prototype.__proto__ 指向了null, 也就到达了
    原型链的最顶端

    作用域链的原理:

    当一个非null, undefined类型的Javasrcipt数据想要获取某个属性值,或者调用某个方法时,如果没有该属性或者方法,那么就会向这个数据的__proto__属性中去查找,

    如果一层还没有,就回继续向上查找,最终查到Object.prototype.__proto__ 因为原型链顶端指向了null,那么就会停止。最终会返回一个undefined

    这个就是原型链的原理

    function Animal() {
        this.name = '猫'
    }
    
    Animal.name = '狗'
    
    Function.prototype.name1 = '猪'
    
    Object.prototype.name2 = '羊'
    
    const animal = new Animal()
    
    console.log(animal.name ,animal.name1, animal.name2) // 猫, undefined, 羊

    注意事项,尽量减少在prototype上增加属性或者操作,那样会修改整个作用域链, 对于JS的运行性能是一种损耗

  • 相关阅读:
    【Azure 应用服务】在Azure App Service多实例的情况下,如何在应用中通过代码获取到实例名(Instance ID)呢?
    【Azure 应用服务】App Service For Windows 中如何设置代理实现前端静态文件和后端Java Spring Boot Jar包
    【Azure Developer】使用Azure Key Vault 的Key签名后,离线验证的一些参考资料
    【Azure Function】调试 VS Code Javascript Function本地不能运行,报错 Value cannot be null. (Parameter 'provider')问题
    【Azure 应用服务】App Service 使用Tomcat运行Java应用,如何设置前端网页缓存的相应参数呢(Xms512m Xmx1204m)?
    【Azure API 管理】APIM添加Logtoeventhub的策略后,一些相关APIM与Event Hub的问题
    【Azure API 管理】为调用APIM的请求启用Trace 调试APIM Policy的利器
    【Azure 事件中心】China Azure上是否有Kafka服务简答
    【Azure 应用服务】探索在Azure上设置禁止任何人访问App Service的默认域名(Default URL)
    【Azure 微服务】记一次错误的更新Service Fabric 证书而引发的集群崩溃而只能重建
  • 原文地址:https://www.cnblogs.com/liquanjiang/p/11369022.html
Copyright © 2011-2022 走看看