本帖最后由 senile_zhang 于 2020-2-28 19:40 编辑
你老师说法不严谨呗,一般而言简单类型都是存于栈的,但string除外罢了
如何理解string这种特殊性呢,我提供两个思路:
思路一:是否继承了Object
可以理解为,区分简单类型和复杂类型不在于看他们是否使用了堆空间,而是在于是否继承了Object。
我们知道所有对象在原型链上一路追溯,都会抵达Object.prototype,换句话说就是都继承了Object。
不过这种思路有两个瑕疵:
-
ES6的Symbol如何认定?
Symbol手动验证的话,可以发现它原型链终点也是Object.prototype,那么应该认定为复杂类型。
但我看网上都认定其是简单类型,虽然还没看到比较权威的说法。
-
继承于 null 的对象如何认定?
有多种方法可以把一个对象的 prototype 设置为 null ,那么此时按这套理论来讲,这个对象就应该是个简单类型了,不符合直觉。
思路二:是否使用堆空间
也就是你老师原来的说法,只不过把string这个例外情况视为一种瑕疵。
当然,这种思路也同样不能解释为什么网上把Symbol列为简单类型。个人觉得网上的说法还是有待检验的
勘误
思路一:是否继承了Object
可以理解为,区分简单类型和复杂类型不在于看他们是否使用了堆空间,而是在于是否继承了Object。
我们知道所有对象在原型链上一路追溯,都会抵达Object.prototype,换句话说就是都继承了Object。
不过这种思路有两个瑕疵:
-
ES6的Symbol如何认定?
Symbol手动验证的话,可以发现它原型链终点也是Object.prototype,那么应该认定为复杂类型。
但我看网上都认定其是简单类型,虽然还没看到比较权威的说法。
-
继承于 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
|