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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 类型转换 number string boolean null undefined symbol object 转...
    阿龙哟阅读 407评论 0 0
  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 13,877评论 0 38
  • 数值 判断NaN更可靠的方法是,利用NaN为唯一不等于自身的值的这个特点,进行判断。 isFinite方法返回一个...
    guyigg阅读 1,178评论 0 2
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,135评论 1 32
  • HTML 5 HTML5概述 因特网上的信息是以网页的形式展示给用户的,因此网页是网络信息传递的载体。网页文件是用...
    阿啊阿吖丁阅读 4,036评论 0 0