以前的博客介绍了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 内存进行彻底的拷贝。