看不懂的隱式轉換(上)--- 基礎鋪墊

前言

看不懂系列 [滑稽.jpg] 最近在找工做,後面的博客內容也算本身的準備了,嘿嘿 其實本身日常看書的時候,也會發現不少東西講的太官話,有點看不懂 有些資料呢,可能又將的太碎片化了, 因此我常常把書上知識點當作一個擴散點,去擴展一些原來不知道的 像這篇,其實講隱式轉換的文章仍是比較多,好的也比較多的 但可能我過小白了,有些一筆帶過的內容好比說,原始值,引用值,toString,valueOf這些一筆帶過 因此在講以前先鋪墊鋪墊 講些原理 PS: 小白一個 歡迎吐槽 嘿嘿嘿git

原始值和引用值

原始值

存儲在棧(stack)中的簡單數據段,也就是說,它們的值直接存儲在變量訪問的位置。github

Undefined、Null、Boolean、Number 和 String 因爲這些原始類型佔據的空間是固定的,因此可將他們存儲在較小的內存區域 - 棧中。這樣存儲便於迅速查尋變量的值。bash

引用值

存儲在堆(heap)中的對象,也就是說,存儲在變量處的值是一個指針(point),指向存儲對象的內存處。函數

object,Array , 函數spa

存儲在變量處的值是一個指針(point),指向存儲對象的內存處。.net

var a = "i am string";
typeof a; // "string"
a instanceof String  //false

var b = new String("i am a string");
typeof b; // "object"
b instanceof String  //true
複製代碼

WTF ???prototype

WHY ???翻譯

一開始看這道題的時候滿臉問號指針

其實吧 這是由於 "i am string" 他是一個原始值code

But

"i am string".length // 8  這些本屬於String的方法卻能被調用
複製代碼

這是應爲在必要時。js語言會把字符串字面量轉換成String對象。也就是你並不須要顯示的建立一個對象valueOf()

toString valueOf()

toString 使用方法

var x = {};
console.log(x.toString());           
//  [object Object]

//特別的用法
toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]

var x = [1,2,3];
x.toString(); //返回'1,2,3'

var x = function(){console.log('lalala')}
x.toString();// 返回'function(){console.log('lalala')}'

var x = 33333;
x.toString();// 返回'33333'
複製代碼

網上copy的一段示例,接下來詳細瞭解一下toString()經常使用語法

obj.toString();

這種使用形式能夠把除null undefined外,全部對象轉爲字符串

//boolean類型
true.toString()  //true
false.toString()  // false
//string類型
var str = "stringlalala"
str.toString()  //"stringlalala"
複製代碼

可是下面出現了一個很是好玩的現象

// Object
var obj = {
    name: "MrZss",
    age: "23"
};
obj.toString(); //[object Object]

// Array
var arr = ["MrZss","23"];
arr.toString();  // "MrZss","23"

//Date
var date = new Date();//
date.toString() //   Wed Feb 27 2019 13:46:35 GMT+0800 (CST)

// Number 
var num = 23;
var num = 23;
console.log(num.toString(2)); //10111 二進制
console.log(num.toString(8)); //27 八進制
console.log(num.toString(16)); //17 十六進制
複製代碼

問題來了 按理來講 Array Date這些對象toString方法 都是從Object對象繼承來的呀。爲何表現徹底不同

友情提醒:Array,RegExp,Date,Number等內置對象中的toString重寫了,用於自己的類型轉化

MDN參考

Object.prototype.toString()

來來來 敲黑板畫重點了

ES6規範描述

實在不行就一鍵翻譯吧 [滑稽.jpg]

這一塊我也去搜了搜大佬的資料,看這個理解的比較詳細

Object.prototype.toString()

因此,可使用Object.prototype上的原生toString()方法判斷數據類型

由於其餘對象例如Array,Date的toString方法都沒覆蓋了 因此仍是須要使用

Object.prototype.toString.call(value) 來調取

Object.prototype.toString.call(null);//」[object Null]」
Object.prototype.toString.call(undefined);//」[object Undefined]」
Object.prototype.toString.call(「abc」);//」[object String]」
Object.prototype.toString.call(123);//」[object Number]」
Object.prototype.toString.call(true);//」[object Boolean]」
....
就不一一列舉了
能夠本身414
複製代碼

Object.prototype.toString.call、instanceof、typeof又有啥不一樣呢

typeof undefined //undefined
typeof null //object
typeof true //boolean
typeof 1.11 //number
typeof "lalala" //string
typeof function(){} //function
typeof new Object() //object
typeof new Array()  //object
typeof new RegExp() //object
複製代碼

typeof 的侷限性

在於 像Array,RegExp,null都會被判斷爲object,這就很尷尬了,沒法去判斷這些內置對象的具體類型

instanceof 的侷限性

在於你必須知道實際類型和父類型再去判斷對與,,對未知構造函數構造的對象來講沒法提早給定,constructor屬性返回的值又不是預期的單純的構造函數名。

Object.prototype.toString 的侷限性

Object.prototype.toString 就很是牛批了,對全部的內建對象都能支持得很是好 惟一很差的地方 自定義的構建的對象,沒法經過原型鏈去查父類型

Object.prototype.toString.call('');  //[object String]
Object.prototype.toString.call(undefined); // [object Undefined]
Object.prototype.toString.call(null); //[object Null]
Object.prototype.toString.call(1111);  // [object Number]
Object.prototype.toString.call(true);  //[object Boolean]
複製代碼

valueOf

這個方法在Array等對象中也會被覆寫

表現形式以下

先盜一個MDN的圖嘿嘿

好了鋪墊完了,待會進入正題

相關文章
相關標籤/搜索