Effective Javascript (类型转换原理)

来源:互联网 发布:花生壳注册免费域名 编辑:程序博客网 时间:2024/06/05 06:25
今天了解到了javascript中的布尔操作符,简单将《Effective Javascript》的翻译和自己的理解整理如下。非(NOT)、与(AND)、或(OR)

1. 逻辑非(!)可以应用于ECMAScript中的任何值。无论这个值是什么数据类型,这个操作符都会返回一个布尔值。
逻辑非操作符首先会将它的操作数转换为一个布尔值,然后对其求反。
引申一下,也就是说,逻辑非操作符也可以用于将一个值转换为与其对应的布尔值。同时使用两个逻辑非(!!)操作符,即会达到这个目的,实际上就会模拟Boolean()转型函数的行为。其中,第一个逻辑非操作会基于无论什么操作数返回一个布尔值,而第二个逻辑非操作则对该布尔值求反,于是就得到了这个值真正对应的布尔值。

2.加法操作符:除了执行常规的算术运算操作之外,如果有一个操作数是字符串,那么就要应用如下规则:
    如果两个操作数都是字符串,那么就将他们拼接起来。
    如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将它们拼接起来
    如果有一个操作数是对象、数值或布尔值,则调用它们的toString()方法取得相应的字符串值,然后再应用前面关于字符串的规则。对于undefined和null,则分别调用String()函数并取得字符串“undefined”和“null”.

3.在原始值和对象包装器中更偏向于原始值(primitive value)
首先解释两个概念:
原始值(primitive value):是存储在栈中的简单数据段,也就是说他们的值直接存在变量访问的位置。
引用值(referrence value):是存储在堆(heap)中的对象,也就是说,存储在变量处(栈中)的值是一个指针,指向存储对象的内存处。

除了Objects,javascript有5种类型的原始值:booleans,numbers,strings,null,和undefined.
同时,标准库为封装booleans,numbers,strings作为一个对象提供了构造函数。你能创建一个String object通过在其中包含一个字符串的值:

var s = new String("hello");

在有些方面,字符串对象的行为和字符串原始值表现的作用是相同的。

但是不同于primitive Strings,a String object is a true object!

typeof "hello";        //"string"
typeof s;                  //“object”

这里有很大的不同,值得注意,因为它意味着你不能用内置的操作符去匹配两个独特的String objects的内容。

var s1= new String("hello");
var s2= new String("hello");
s1===s2;          //false  它们引用了堆中不同的内存

因为每个String object 都是一个单独的对象(object),它只能永久的等于它自身。即使用不严格的等于操作符也是同样的效果。

s1==s2;          //false

因为这些封装类型的行为并不是完全正确。他们主要存在的原因是它们有一些比较方便的方法。javaScript为能进行一些其他的隐式转换制造了这些方便:你能在一个原始值的基础上调用一些方法和抽取一些属性。
比如:“hello”.toUpperCase();             //“HELLO”

对于这个隐式封装存在一个奇怪的现象就是你能在原始值的基础上对它设置属性且在本质是没有必然影响的!

"hello".someProperty = 17;
"hello".someProperty;          // undefined

因为当这个隐式封装每次发生的时候就会产生了一个新的字符串对象,当你在第一个封装对象上设置了一个属性,进行了更新,但是它并没有持续的影响。在原始值的基础上设置属性是没有任何意义的。但是这个行为值得我们所注意。它证明了这是另外一种能隐藏类型错误的实例:如果你在你所期待的一个对象上要设置一个属性值,但是却错误的采用了原始值,你的程序会简单的默认的忽略这个更新然后继续执行其以后的代码。这样就会轻易的导致一些未被发现的错误,让诊断变的艰难。

在理解上面这段代码的同时,我又翻看了《javascript权威指南》这本书上,它的解释是:

在此有两点需要谨记:
1. Object wrappers for primitive types do not have the same behavior as their primitive values when compared for equality. 
2. Getting and setting properties on primitives implicitly creates object wrappers

原创粉丝点击