以前的博客介紹了JS中的各類數據類型,那麼在js當中,不一樣的數據類型怎麼相互轉換呢,如下是常見的不一樣數據類型轉換的用法。git
(1).toString() // '1'
true.toString() // 'true'
null.toString() // 報錯
undefined.toString() // 報錯
({}).toString() // "[object Object]"
複製代碼
toString
方法適用於number
類型和boolean
類型,可是對於null
和undefined
,使用這種方法會報錯,對於object
,toSring
方法結果不正確,結果永遠是"[object Object]"
。面試
console.log
其實就是用的這個原理,理論上 console.log
只能接受字符串。瀏覽器
console.log
打印出來的實際上是有引號的可是瀏覽器沒打,
console.log(1)
打印出來的至關於
console.log((1).toString)
因此
console.log
若是發現不是字符串,會自動調用
toString
這個API 轉化爲字符串,
object
的
key
也是會這樣。
String()
該方法適用於全部數據類型(除了對象,結果同toString())bash
String(1) // '1'
String(true) // 'true'
String(null) // 'null'
String(undefined) // 'undefined'
String({}) // "[object Object]"
複製代碼
使用+運算符加上空字符串,功能更強大,能夠 +null 和 +undefined。網絡
1 + '' // '1'
true + '' // 'true'
obj+""; // "[object Object]"
'' + null // 'null'
'' + undefined // 'undefined'
1 + '1' // '11'
複製代碼
+
若是發現左右任意一邊有字符串,它就會嘗試把另一邊也變成字符串,+
老是但願能夠獲得兩個字符串。函數
1 + '1'
因爲 +
只能加相同類型的東西,因此它會嘗試去改變這個類型,優先會嘗試轉化爲字符串,等價於 (1).toString + '1'
。spa
Boolean(123); // true
Boolean("abc"); // true
Boolean({}); // true
Boolean(''); // false
複製代碼
用任何東西取反兩次就會獲得一個 Boolean
操作系統
!!"abc" ; // true
!!'' ; // false
!!{} ; // true
複製代碼
falsy 是在 Boolean
上下文中認定可轉換爲 false
的值;3d
0 、 NaN 、 null 、 undefined 、‘’(空字符串)、false
複製代碼
使用 Number
函數,能夠將任意類型的值轉化成數值。若是沒法轉換爲數字,那麼 Number()
函數返回 NaN
。code
Number(123) // 123
Number('123') // 123
Number(true) // 1
Number(null) // 0
Number('123.45#') // NaN
複製代碼
parseInt
方法用於將字符串轉爲整數。
parseInt('123') // 123
複製代碼
若是字符串頭部有空格,空格會被自動去除。
parseInt(' 81') // 81
複製代碼
若是 parseInt
的參數不是字符串,則會先轉爲字符串再轉換。
parseInt(1.23) // 1
// 等同於
parseInt('1.23') // 1
複製代碼
字符串轉爲整數的時候,是一個個字符依次轉換,若是遇到不能轉爲數字的字符,就再也不進行下去,返回已經轉好的部分。
parseInt('8a') // 8
複製代碼
parseFloat
方法用於將一個字符串轉爲浮點數。
parseFloat('3.14') // 3.14
複製代碼
若是字符串符合科學計數法,則會進行相應的轉換。
parseFloat('314e-2') // 3.14
複製代碼
若是字符串包含不能轉爲浮點數的字符,則再也不進行日後轉換,返回已經轉好的部分。
parseFloat('3.14more non-digit characters') // 3.14
複製代碼
parseFloat
方法會自動過濾字符串前導的空格。
parseFloat('\t\v\r12.34\n ') // 12.34
複製代碼
若是參數不是字符串,或者字符串的第一個字符不能轉化爲浮點數,則返回NaN
。
parseFloat([]) // NaN
複製代碼
123 - 0
複製代碼
+ 123 // 123
+ '-1' // -1
複製代碼
什麼是內存呢,舉個例子:你買一個8G 的內存條,操做系統開機即佔用 512MB,Chrome 打開即佔用 1G 內存, Chrome 各每一個網頁分配必定數量的內存, 這些內存要分給頁面渲染器、網絡模塊、瀏覽器外殼和 JS 引擎(V8引擎)。 JS 引擎將內存分爲代碼區和數據區, 咱們只研究數據區。 數據區分爲 Stack(棧內存)和 Heap(堆內存)。 簡單類型的數據(如Number,string等)直接存在 Stack 裏, 複雜類型的數據(object對象)是把 Heap 地址存在 Stack 裏。
對象的存儲方式是在stack內存存儲一個地址,造成對對象的引用,地址指向heap內存的某個位置,這樣才能達到能夠隨時爲對象添加或刪除內容的目的。因此有句話這麼說,object是對象的引用。它在stack內存存的是地址,而不像其餘數據類型直接把內容存在stack內存。
var a = 1
var b = a
b = 2
請問 a 顯示是幾?
複製代碼
在內存圖能夠看出
a
仍是等於
1
。
var a = {name: 'a'}
var b = a
b = {name: 'b'}
請問如今 a.name 是多少?
複製代碼
等於號製做一件事情,就是把右邊的東西存到左邊,由內存圖能夠看出
a.name
是
'a'
。
var a = {name: 'a'}
var b = a
b.name = 'b'
請問如今 a.name 是多少?
複製代碼
在內存圖能夠看出
a.name
是
'b'
var a = {name: 'a'}
var b = a
b = null
請問如今 a 是什麼?
複製代碼
基本類型在棧內存中,對象是複雜類型在堆內存中,因此
a
是等於自己。
var a = {n:1};
var b = a;
a.x = a = {n:2};
alert(a.x);
alert(b.x);
複製代碼
瀏覽器看到
a.x = a = {n:2};
的時候會先肯定
a
的值,
a
是內存地址34,而後申明對象
{n:2}
的內存地址爲54,右邊的
a
就等於內存54了,而前面的
a
已經肯定了是內存34的對象,不會重複改變
a
的值。瀏覽器是先看左邊,再往右看的,只不過是看了右邊以後,算完了再回到左邊。
若是一個對象沒有被引用,它就是垃圾,將會被回收。
var fn = function(){}
document.body.onclick = fn
fn = null
複製代碼
fn
是垃圾將被回收嗎?
fn
還被
document
引用,因此不是垃圾不會被回收。
若是如今把頁面關了,fn 是垃圾嗎?
fn
是垃圾將被回收,由於頁面關閉後document
就不存在了,後面的對象失去了引用。裏面三個對象相鏈接,可是外面沒有鏈接,這三個都將被回收。
可是 IE6 有個 BUG,會認爲這三個不是垃圾,會把這三個內存一直留着。只要不關閉整個IE,只關掉一個 tab 是沒有用的,這樣垃圾會愈來愈多,內存不能從新被利用。IE6 沒法在頁面關閉的時候,正常的把那些 onclick
對應的函數給標記爲垃圾。
// 解決方法,把全部的事件監聽置爲 null
window.onunload = function(){
document.bady.onclick = null
}
複製代碼
這就是所謂的內存泄漏 ,內存泄漏就是因爲瀏覽器的一些bug,使得該被標記爲垃圾的沒有標記爲垃圾,而後內存就會被永久的佔用。
var a = 1
var b = a
b = 2 //這個時候改變 b
a 徹底不受 b 的影響
那麼咱們就說這是一個深複製
複製代碼
對於簡單類型的數據來講,賦值就是深拷貝。對於複雜類型的數據(對象)來講,纔要區分淺拷貝和深拷貝。
var a = {name: 'frank'}
var b = a
b.name = 'b'
a.name === 'b' // true
複製代碼
由於咱們對 b 操做後,a 也變了。 什麼是深拷貝了,就是對 Heap 內存進行徹底的拷貝。