JS数据类型(二)

数值的转换

任何数据类型转换成string类型:

  • x.tostring()
  • String(x)
  • x + ' ' //x 为要转化的类型

转换为 boolean 类型:

  • boolean(x)
  • !!x //x为要转换的类型

任意类型转换为 number:

  • number(''1'')===1
  • parseInt('1',10)===1
  • parseFloat('1.234')===1.234
  • '1' - 0 ===1 //老手常用
  • +'1' ===1

字符串

JavaScript 使用 Unicode 字符集。JavaScript 引擎内部,所有字符都用 Unicode 表示。每个字符在 JavaScript 内部都是以16位(即2个字节)的 UTF-16 格式储存。也就是说,JavaScript 的单位字符长度固定为16位长度,即2个字节。
连接运算符(+)可以连接多个单行字符串,将长字符串拆成多行书写,输出的时候也是单行。

var longString = 'Long '
  + 'long '
  + 'long '
  + 'string';

转义符"\":用来表示一些特殊字符
需要用反斜杠转义的特殊字符,主要有下面这些:
\0 : null(\u0000)
\b :后退键(\u0008)
\f : 换页符(\u000C)
\n : 换行符(\u000A)
\r : 回车键(\u000D)
\t : 制表符(\u0009)
\v :垂直制表符(\u000B)
' : 单引号(\u0027)
" :双引号(\u0022)
\ :反斜杠(\u005C)

反斜杠还有三种特殊用法。
(1)\HHH
反斜杠后面紧跟三个八进制数(000到377),代表一个字符。HHH对应该字符的 Unicode 码点,比如\251表示版权符号。显然,这种方法只能输出256种字符。
(2)\xHH
\x 后面紧跟两个十六进制数(00到FF),代表一个字符。HH对应该字符的 Unicode 码点,比如\xA9表示版权符号。这种方法也只能输出256种字符。
(3)\uXXXX
\u 后面紧跟四个十六进制数(0000到FFFF),代表一个字符。XXXX对应该字符的Unicode 码点,比如\u00A9表示版权符号。

'\251' // "©"
'\xA9' // "©"
'\u00A9' // "©"

'\172' === 'z' // true
'\x7A' === 'z' // true
'\u007A' === 'z' // true

'\a'// a是一个正常字符,\被省略
// "a"

length属性可以返回字符串的长度。该属性也是无法改变的,字符串内部的单个字符无法改变和增删的。

JavaScript 原生提供两个 Base64 相关的方法:

  • btoa():任意值转为 Base64 编码
  • atob():Base64 编码转为原来的值
var string = 'Hello World!';
btoa(string) // "SGVsbG8gV29ybGQh"
atob('SGVsbG8gV29ybGQh') // "Hello World!"

要将非 ASCII 码字符转为 Base64 编码,必须中间插入一个转码环节,再使用这两个方法。

function b64Encode(str) {
  return btoa(encodeURIComponent(str));
}

function b64Decode(str) {
  return decodeURIComponent(atob(str));
}

b64Encode('你好') // "JUU0JUJEJUEwJUU1JUE1JUJE"
b64Decode('JUU0JUJEJUEwJUU1JUE1JUJE') // "你好"

对象

简单来说,对象就是一组"键值对"的集合,是一种无序的复合数据类型。

var obj = {
  foo: 'Hello',  //key: value
  bar: 'World' //key:valre
};

对象的所有键名都是字符串(ES6 又引入了 Symbol 值也可以作为键名),所以加不加引号都可以。如果键名是数值,会被自动转为字符串。如果键名不符合标识名的条件(比如第一个字符为数字,或者含有空格或运算符),且也不是数字,则必须加上引号,否则会报错。

对象的引用
如果不同的变量名指向同一个对象,那么它们都是这个对象的引用,也就是说指向同一个内存地址。修改其中一个变量,会影响到其他所有变量。

var o1 = {};
var o2 = o1;

o1.a = 1;
o2.a // 1

o2.b = 2;
o1.b // 2

上面代码中,o1和o2指向同一个对象,因此为其中任何一个变量添加属性,另一个变量都可以读写该属性。
此时,如果取消某一个变量对于原对象的引用,不会影响到另一个变量。

var o1 = {};
var o2 = o1;

o1 = 1;
o2 // {}

上面代码中,o1和o2指向同一个对象,然后o1的值变为1,这时不会对o2产生影响,o2还是指向原来的那个对象。
但是,这种引用只局限于对象,如果两个变量指向同一个原始类型的值。那么,变量这时都是值的拷贝。

var x = 1;
var y = x;

x = 2;
y // 1

上面的代码中,当x的值发生变化后,y的值并不变,这就表示y和x并不是指向同一个内存地址。

普通数据类型和对象的区别:

内存图

  1. 你买一个 8G 的内存条
  2. 操作系统开机即占用 512MB
  3. Chrome 打开即占用 1G 内存
  4. Chrome 各每个网页分配一定数量的内存
  5. 这些内存要分给页面渲染器、网络模块、浏览器外壳和 JS 引擎(V8引擎)
  6. JS 引擎将内存分为代码区和数据区
  7. 我们只研究数据区
  8. 数据区分为 Stack(栈内存)和 Heap(堆内存)
  9. 简单类型的数据直接存在 Stack 里
  10. 复杂类型的数据是把 Heap 地址存在 Stack 里,所以遇到这类问题就画图,不要分析。

    基本类型没有属性,但可以 .toString 是因为创建了一个temp临时对象,当.toString 时就把 temp 里的属性拿过来后temp再被回收。

面试题

var a = 1
var b = a
b = 2
请问 a 显示是几?  
题解一.png
var a = {name: 'a'}
var b = a
b = {name: 'b'}
请问现在 a.name 是多少?
题解二.png
var a = {name: 'a'}
var b = a
b.name = 'b'
请问现在 a.name 是多少?
题解三.png
var a = {name: 'a'}
var b = a
b = null
请问现在 a 是什么?
图解四.png



值类型作为函数的参数传递的是值,引用类型作为函数的参数传递的是地址(引用)。

内存图.png

面试坑题.png
题型二.png
题型一.png

你可能感兴趣的:(JS数据类型(二))