吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2083|回复: 22
收起左侧

[已解决] JS基础:字符串的不可变性 VS 简单类型数据类型在内存中的存储

[复制链接]
clearwater 发表于 2020-2-28 15:35
本帖最后由 clearwater 于 2020-2-28 17:50 编辑

我在跟某马的前端视频学习。

1、老师在视频中某个小节,提到字符串的不可变性。-----这个我看懂了。
代码如下:
[Asm] 纯文本查看 复制代码
   // 字符串的不可变性
        var str = 'andy';
        console.log(str);
        str = 'red';
        console.log(str);

老师说,andy 并没有被 red 覆盖掉,而是red 在内存中开辟了一个新的空间,然后把str 指向 red.
001.PNG

2、然后老师又在后面的小节提到,简单数据类据包括:数字型,字符串型等等。他举例说,简单数据内型的数字型是把值替换掉。---这个我也懂了。
[JavaScript] 纯文本查看 复制代码
 var num = 10;
 num = 20;

002.png


我的问题是上面的第1点,和第2点,好象是矛盾的。第1点是字符串的数据保持不变,只是把变量名指向新的字符串值域;第2点,是把10替换为20.
是不是除了字符串外,简单数据内型(数字型、布尔型,null , undefined)全部在栈中替换值,而字符串型则是开劈新空间?



发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

senile_zhang 发表于 2020-2-28 17:44
本帖最后由 senile_zhang 于 2020-2-28 19:40 编辑
clearwater 发表于 2020-2-28 16:15
谢谢您和楼上另位二位大神的帮助。

你老师说法不严谨呗,一般而言简单类型都是存于栈的,但string除外罢了

如何理解string这种特殊性呢,我提供两个思路:

思路一:是否继承了Object

可以理解为,区分简单类型和复杂类型不在于看他们是否使用了堆空间,而是在于是否继承了Object。
我们知道所有对象在原型链上一路追溯,都会抵达Object.prototype,换句话说就是都继承了Object。

不过这种思路有两个瑕疵:

  1. ES6的Symbol如何认定?
    Symbol手动验证的话,可以发现它原型链终点也是Object.prototype,那么应该认定为复杂类型。
    但我看网上都认定其是简单类型,虽然还没看到比较权威的说法。

  2. 继承于 null 的对象如何认定?
    有多种方法可以把一个对象的 prototype 设置为 null ,那么此时按这套理论来讲,这个对象就应该是个简单类型了,不符合直觉。


思路二:是否使用堆空间

也就是你老师原来的说法,只不过把string这个例外情况视为一种瑕疵。

当然,这种思路也同样不能解释为什么网上把Symbol列为简单类型。个人觉得网上的说法还是有待检验的



勘误
思路一:是否继承了Object

可以理解为,区分简单类型和复杂类型不在于看他们是否使用了堆空间,而是在于是否继承了Object。
我们知道所有对象在原型链上一路追溯,都会抵达Object.prototype,换句话说就是都继承了Object。

不过这种思路有两个瑕疵:

  1. ES6的Symbol如何认定?
    Symbol手动验证的话,可以发现它原型链终点也是Object.prototype,那么应该认定为复杂类型。
    但我看网上都认定其是简单类型,虽然还没看到比较权威的说法。

  2. 继承于 null 的对象如何认定?
    有多种方法可以把一个对象的 prototype 设置为 null ,那么此时按这套理论来讲,这个对象就应该是个简单类型了,不符合直觉。

symbol 没有原型链,的确是简单类型, 对简单类型使用 Object.getPrototyeOf() 会发生强制类型转换,将其包装成一个对象。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf#Notes

我忘记了这一点,导致以为下面的代码为 true 就意味着symbol继承于Object

Object.getPrototypeOf( Object.getPrototypeOf(Symbol()) ) === Object.prototype    //true

类似地,对number和boolean使用 Object.getPrototypeOf()也发生type coercion

实际上,应该用 instanceof 操作符来验证是否存在于原型链的问题

Symbol() instanceof Object    //false

免费评分

参与人数 1热心值 +1 收起 理由
clearwater + 1 谢谢@Thanks!

查看全部评分

cxbb 发表于 2020-2-28 15:38
看起来厉害

免费评分

参与人数 1吾爱币 -1 收起 理由
clearwater -1 请勿灌水,提高回帖质量是每位会员应尽的义务!

查看全部评分

吐槽户 发表于 2020-2-28 15:59
我也是半桶水
在学java,看到楼主的问题
说一下自己的看法,
基本数据类型在栈内存里面是值
字符串是引用数据类型在栈内存里面是引用堆内存的地址

免费评分

参与人数 1热心值 +1 收起 理由
clearwater + 1 谢谢@Thanks!

查看全部评分

王辰瑞 发表于 2020-2-28 15:59
我只记得JS是弱类型语言,不是自带类型转换么。。估计内部处理方式不一样吧。。我只记得JAVA的String new出来的是在堆里,赋值的在栈里,至于那些冗余的堆里之前创建的VM虚拟机会自动回收
井右寺 发表于 2020-2-28 16:04
好像看过一种说法
js的简单数据类型,是直接存储在栈里面的
对象等复杂数据类型,地址是存在栈的,实际数据是保存在堆里的。。。
按照这样来解释的话,js是直接操作栈的,简单数据类型就被直接替换了。
而字符串等,栈地址不变,但栈区存储的地址指向变了,指向堆区开辟的新空间,而堆的管理是由GC控制的,并不会被立即释放。
具体原理也不太清楚,这个东西需要注意的就是,引用类型和值类型的区别了。应该是类比c的指针和值。
wubo777 发表于 2020-2-28 16:06
看起来厉害
 楼主| clearwater 发表于 2020-2-28 16:12

不来回复这些没用回答,手会痒吗?想灌水,去水区。

 楼主| clearwater 发表于 2020-2-28 16:15
本帖最后由 clearwater 于 2020-2-28 16:18 编辑
井右寺 发表于 2020-2-28 16:04
好像看过一种说法
js的简单数据类型,是直接存储在栈里面的
对象等复杂数据类型,地址是存在栈的,实际数 ...

谢谢您和楼上另位二位大神的帮助。

s的简单数据类型,是直接存储在栈里面的
对象等复杂数据类型,地址是存在栈的,实际数据是保存在堆里的。。。

我引用您的上面文字和老师的说法是一样的。

但是老师说,string也是简单数据类型啊。应该也是存在栈中才对。下面红字的出处是老师的笔记。

2.1 简单数据类型
                简单类型基本数据类型值类型):在存储时变量中存储的是值本身,包括string ,number,boolean,undefined,null

2.2 复杂数据类型
                复杂数据类型(引用类型):在存储时变量中存储的仅仅是地址(引用),通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等;

井右寺 发表于 2020-2-28 16:32
clearwater 发表于 2020-2-28 16:15
谢谢您和楼上另位二位大神的帮助。

http://www.imooc.com/wenda/detail/476583
不知道这个说法对不对
好像在java里面,字符串直接就是对象,直接赋值相当于new。
我刚刚试了下,js里面有String对象,也有string类型,二者居然不是一样的

免费评分

参与人数 1热心值 +1 收起 理由
clearwater + 1 谢谢@Thanks!

查看全部评分

幼稚鬼 发表于 2020-2-28 16:38
JS的数据类型又可分为两种,这里讨论ES5
1)基本类型(又叫原始类型):
包括:Undefined、Null、Boolean、Number、String
2)引用类型:
包括:Array 、 Object 、 function 、Date 、RegExp.


两者的区别是基本类型变量存的是数据的具体值,而引用类型变量保存的是值的引用


但字符串(string)类型比较特殊,因为js中的字符串长度可变,不能存在大小固定的地址空间当中,可以看做是:行为与基本类型相似的不可变引用类型。


上诉内容借鉴了百度知道的回答:https://zhidao.baidu.com/question/1387978414020167860.html

免费评分

参与人数 1吾爱币 +1 收起 理由
clearwater + 1 热心不够不用。谢谢你

查看全部评分

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-26 18:38

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表