【JavaScript】——“重学前端”01数据类型

        我们必须认识到 3 与 new Number(3) 是完全不同的值,它们一个是 Number 类一个是对象类型
Number、String 和 Boolean,三个构造器是两用的,当跟 new 搭配时,它们产生对象,当直接调用时,它们表示强制类型转换

Symbol 函数比较特殊,直接用 new 调用它会抛出错误,但它仍然是 Symbol 对象的构器。

很多实践中推荐禁止使用“ ==”,而要求程序员进行显式地类型转换后,用 === 比较。

字符串到数字的类型转换: 

        在不传入第二个参数的情况下,parseInt 只支持 16 进制前缀“0x”,而且会忽略非数字
字符,也不支持科学计数法。

        在一些古老的浏览器环境中,parseInt 还支持 0 开头的数字作为 8 进制前缀,这是很多错误的来源。所以在任何环境下,都建议传入 parseInt 的第二个参数

        而 parseFloat 则直接把原字符串作为十进制来解析,它不会引入任何的其他进制。

        多数情况下,Number 是比 parseInt 和 parseFloat 更好的选择。

装箱转换 :

        每一种基本类型 Number、String、Boolean、Symbol 在对象中都有对应的类,所谓装箱转换,正是把基本类型转换为对应的对象,它是类型转换中一种相当重要的种类。

        全局的 Symbol 函数无法使用 new 来调用,但我们仍可以利用装箱机制来得到一个 Symbol 对象,我们可以利用一个函数的 call 方法来强迫产生装箱。

//我们定义一个函数,函数里面只有 return this.
//然后我们调用函数的 call 方法到一个Symbol 类型的值上.
//这样就会产生一个 symbolObject。 
var symbolObject = (function(){ return this; }).call(Symbol("a"));
 console.log(typeof symbolObject); //object
 console.log(symbolObject instanceof Symbol); //true
 console.log(symbolObject.constructor == Symbol); //true

        装箱机制会频繁产生临时对象,在一些对性能要求较高的场景下,我们应该尽量避免对基本类型做装箱转换。

        使用内置的 Object 函数,我们可以在 JavaScript 代码中显式调用装箱能力。

 var symbolObject = Object(Symbol("a"));
 console.log(typeof symbolObject); //object
 console.log(symbolObject instanceof Symbol); //true
 console.log(symbolObject.constructor == Symbol); //true

在 JavaScript 中,没有任何方法可以更改私有的 Class 属性,因此
Object.prototype.toString 是可以准确识别对象对应的基本类型的方法,它比 instanceof
更加准确。
但需要注意的是,call 本身会产生装箱操作,所以需要配合 typeof 来区分基本类型还是对
象类型。

拆箱转换:

拆箱转换会尝试调用 valueOf toString 来获得拆箱后的基本类型。如果 valueOf 和
toString 都不存在,或者没有返回基本类型,则会产生类型错误 TypeError。

        进行 o*2 这个运算的时候,你会看见先执行了 valueOf,接下来是toString,最后抛出了一个 TypeError,这就说明了这个拆箱转换失败了。

 var o = {
     valueOf : () => {console.log("valueOf"); return {}},
     toString : () => {console.log("toString"); return {}}
 }

 o * 2
 // valueOf
 // toString
 // TypeError

        到 String 的拆箱转换会优先调用 toString。我们把刚才的运算从 o*2 换成 String(o),那
么你会看到调用顺序就变了。

 var o = {
     valueOf : () => {console.log("valueOf"); return {}},
     toString : () => {console.log("toString"); return {}}
 }
 String(o)
 // toString
 // valueOf
 // TypeError

实践问题:

如果我们不用原生的 Number 和 parseInt,用 JS 代码实现String 到 Number 的转换,该怎么做呢?

let StringToNumber = (str)=>{
    let arr = str.trim().split('')
    let sign = arr[0] === '-' ? -1 : 1 //sign标记符号
    if (sign === -1 || str[0] === '+') {  //如果有符号就删除
        arr.shift()
    }
    return sign * arr.reduce((total, cur)=>(
        total * 10 + (cur >= '0' && cur <= '9' ? (cur - '0') : NaN)
    ))
}

猜你喜欢

转载自blog.csdn.net/qq_50497708/article/details/128171028