最近不看犀牛书了,翻译的很烂很别扭,尤其是原型一本一塌糊涂。后来经过同事介绍,买了这个js高级程序设计,然后继续努力读,不吐不快,继续讲js中有新鲜感的包装类型。
一:字符串
说到String类型,还是挺有意思的。通常我们定义这样的字符串类型,如下图所示:
但是js中有一个特别的地方,就是字符串类型是基本类型,不是引用类型,这意味着字符串的值存储在“栈”上,但是很多语言都不是这样。比如C#我觉得js不是引用类型是情有可原的。毕竟不能玩多线程,C#中一个线程的栈空间只分配1M。如果字符串是C#中的值类型,它将使堆栈爆炸。
然后下一个问题来了。我们经常对字符串执行一系列操作,比如子字符串。下图:
就像我刚才说的,string的值直接存储在栈上,那么它怎么可能有substring呢?根据官网的解释,s会用String类型包装成引用类型。然后使用String类型的内部实现,就像String在内部定义substring方法一样,所以上面的代码应该在js内部这样实现。
var s=新字符串(' hello ')var r=s . substring(3)s=' hello '
可以看到,实际上包装器类型只是在执行代码的瞬间将S包装成string引用类型,然后调用String引用类型下的substring方法,再将“hello”值再次赋给S。最后的效果是s='hello ',r='lo '。如果你仔细观察,你会发现,如果我动态地给S附加一个属性,比如颜色,那么你再次读取颜色的。
如果你理解我上面说的原理,console.log(s.color)等于undefined也就不足为奇了。我们可以看到,当我使用s.color='red '时,js引擎发现有一种方法可以调用该属性,它会立即在后台将其动态打包为String类型。然后,将一个颜色=红色的属性添加到字符串中,然后立即将s的值重置为“hello”(s=“hello”)。然后,当您从console.log输出s.color时,js引擎判断有另一种方法可以调用该属性。当新字符串(' hello ')再次被删除时,在这个新字符串类型下自然没有颜色属性,因此返回undefined
就像我刚才说的,这个打包操作是js在后台动态追加和删除的,把基本类型转换成引用类型,那么两者有什么区别呢?
1:不用说,这是一堆又一堆。如果你对C#有更多的了解,你可以把它想象成一个盒子和unbox操作。
2:我们知道所有引用类型都是从对象继承的。注意引用类型不应该被面向对象所混淆。例如,在C#中,所有类型都是Object的子类,而在js中,
里面不是这样。我们可以用实例来看看。
二:布尔型
如果你能理解字符串包装器类,那么布尔包装器类实际上和它的原理是一样的,但是在布尔类型的使用上有一个注意事项。我们知道引用类型总是真的,除非它是空的或未定义的,并且这个布尔类型执行这个框操作,如下图所示:
我们可以看到,此时的B不是一个简单的基本类型,而是一个引用类型。这时,我再也不能“与或”我想要的结果。还有一个Number包装类,没什么好注意的,就不说了。