美文网首页
JS 类型转换和对象引用

JS 类型转换和对象引用

作者: simplue | 来源:发表于2018-11-06 00:31 被阅读0次

    数据类型转换

    任意类型转string:

    // 使用变量属性 toString(),null,undefined等不可用
    (1).toString()
    "1"
    
    // 与空字符串相加,推荐
    1 + ""
    "1"
    
    // 使用 String()
    window.String(1)
    "1"
    

    任意类型转boolean:

    // 使用Boolean()
    Boolean(1)
    true
    Boolean(0)
    false
    Boolean(undefined)
    false
    
    // 两次取反
    !!NaN
    false
    !!1
    true
    

    其他类型转boolean后值为false的只有5种情况:nullundefined0""NaN,这五个由称作falsy值

    字符串转number:

    // Number()
    Number('1')
    1
    
    // parseInt()
    parseInt('1')
    1
    
    parseInt('a1')
    NaN
    
    parseInt('1a')
    1
    
    // parseFloat()
    parseFloat('1')
    1
    
    // 与 0 相减
    '1' - 0
    1
    
    // 取正值
    + '1'
    1
    

    引用

    js数据在存储简单类型的数据时(即通常情况下的非object类型数据),都放在stack内存中,而复杂类型数据(object)存在heap内存中。因此在定义一个对象时(如var a = {a: 'b'}),变量a实际上是一个对象(object)的引用,换言之,即在取值时是通过stack中存储的地址来“间接”的获取值,而不是像简单类型那样直接获取。

    数据存储示意.png

    接下来就通过几个示例来理解数据存储

    // 简单类型存储
    var a = 1, b = a
    b === 1
    true
    
    // 改变b,a的值并不会改变,因为简单类型存储的值而不是引用
    b = 2
    a === 1
    true
    
    // 替换引用 1
    // 执行后 {name: 'foo'} 被两个变量引用
    var a = {name: 'foo'}, b = a
    
    // 这里是用 {name: 'bar'} 替换了b的先前的引用 {name: 'foo'},而不是修改了先前的引用
    b = {name: 'bar'}
    a.name=== 'foo'
    true
    
    // 替换引用 2
    var a = {name: 'foo'}, b = a
    
    // 同样的,这里用null替换了b的先前的引用 {name: 'foo'},所以a的引用还是不变
    b = null
    a.name === 'foo'
    true
    
    // 替换引用 3
    var fn = function(){}
    document.body.onclick = fn
    
    fn = null
    document.body.onclick === null
    false
    
    // 修改引用
    var a = {name: 'foo'}, b = a
    
    // 这里修改的是引用的内部值,而a,b引用了同一个对象,所以a.name也跟着变更
    b.name = 'bar'
    a.name === 'bar'
    true
    
    // 让人头大的引用
    var a = {name: 'foo'}, b = a
    
    // 此处的坑在于,a.x 的 a 是赋值前就确定的,那么这一句就相当于下面两句
    //    > a.x = {name: 'bar'}
    //    > a = {name: 'bar'}
    // 执行结果
    //    a -> {name: 'bar'};  b -> {name: 'foo', x: {'name': 'bar'}}
    a.x = a = {name: 'bar'}
    
    a.x === undefined
    true
    b.x.name === 'bar'
    true
    

    引用自身

    // 这种引用自身的方法无效,因为a先前没有被定义,所以是undefined
    var a = {name: 'foo', self: a}
    a.self === undefined
    true
    
    // 正确方式
    var a = {name: 'foo'}
    a.self = a
    
    // 成功引用自身
    a.self
    {name: "foo", self: {…}}
    
    a.age = 18
    
    a.self
    {name: "foo", self: {…}, age: 18}
    
    // 可以“无限”self下去
    a.self.self.self.name
    "foo"
    

    垃圾回收,简而言之没有被引用的值,就会被回收

    // 不考虑其他因素(即a,b的值没有其他引用的理想情况下),执行完下面这句后,{name: 'foo'}就变成垃圾了
    // 但是变量被回收的具体时间取决与浏览器的回收策略
    var a = {name: 'foo'}, b = {name: 'bar'}, a = b
    

    相关文章

      网友评论

          本文标题:JS 类型转换和对象引用

          本文链接:https://www.haomeiwen.com/subject/omdexqtx.html