首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
函数参数与返回值
传递变长参数
defer 和追踪
内置函数
递归函数
将函数作为参数
闭包
应用闭包:将函数作为返回值
使用闭包调试
计算函数执行时间
通过内存缓存来提升性能
声明和初始化
切片
For-range 结构
切片重组(reslice)
切片的复制与追加
字符串、数组和切片的应用
声明、初始化和 make
测试键值对是否存在及删除元素
for-range 的配套用法
map 类型的切片
map 的排序
将 map 的键值对调
标准库概述
regexp 包
锁和 sync 包
精密计算和 big 包
自定义包和可见性
为自定义包使用 godoc
使用 go install 安装自定义包
自定义包的目录结构、go install 和 go test
通过 Git 打包和安装
Go 的外部包和项目
在 Go 程序中使用外部库
结构体定义
使用工厂方法创建结构体实例
使用自定义包中的结构体
带标签的结构体
匿名字段和内嵌结构体
方法
类型的 String() 方法和格式化描述符
垃圾回收和 SetFinalizer
当前位置:
首页>>
技术小册>>
go编程权威指南(二)
小册名称:go编程权威指南(二)
数据类型就是 JavaScript 中可操作的数据的类型。 数据类型分为`值类型`与`引用类型`。 在 ES6 之前,主要有以下数据类型: * 值类型 * 字符串 * 数字 * 布尔 * null * undefined * 引用类型 * 对象 * 数组 * 函数 1\. 为什么需要不同的数据类型 ---------------- 在学习自然数学的时候,所有的加法减法等操作都是针对数字的,数字加上操作符让他们有了意义。 在学习语文课的时候,不同的词语可以组合成句子,主谓宾语法与词语相互结合赋予了句子意义。 在 JavaScript 中也是如此,配合数据类型才能知道怎么对数据进行操作。 上一小节有提到的字符串与数字就是如此。 如 `3 + 4`,JavaScript碰到两边都是数字,就会做对应的加法操作。 程序需要不同类型的数据表示不同的内容,分别做对应的处理。 2\. 值类型 ------- ### 2.1 字符串 字符串由字符组成,字符串在使用的时候会使用双引号`(")`或者单引号`(')`包裹。 var str1 = '字符串'; var str2 = "字符串"; console.log(str1); // 输出:"字符串" console.log(str2); // 输出:"字符串" 上述例子中,两个变量都是字符串类型的,可以双引号和单引号包裹的结果是一样的。 但是如果需要在双引号包裹的字符串中使用双引号,或者在单引号包裹的字符串中使用单引号,需要使用`\`进行转义,否则会报错,因为 JavaScript 无法知道字符串的结束位置。 var str1 = '使\'用\'单\'引\'号'; var str2 = "使\"用\"双\"引\"号"; console.log(str1); // 输出:"使'用'单'引'号" console.log(str2); // 输出:"使"用"双"引"号" // 以下代码会报错 var str3 = "哼"!"; var str4 = ''哼!'; 大部分开发者会使用单引号包裹字符串。 因为为了网页的动态展示、复杂交互等,需要用 JavaScript 书写 HTML 模版,而 HTML 的属性按照习惯是使用双引号包裹的(XML 标准允许单引号和双引号,在 HTML5 的标准中甚至不需要书写引号)。 这样如果使用 JavaScript 中的字符串表示 HTML 就会变成如下情况: var html = "<div class=\"title text-red\" style=\"display: inline-block;\">我是一个红色的标题</div>"; 为了契合书写 HTML 的习惯,防止代码中充斥的大量的转义,就会使用如下使用单引号的形式。 var html = '<div class="title text-red" style="display: inline-block;">我是一个红色的标题</div>'; ### 2.2 数字 数字是最好理解的一种类型,因为生活中都会接触到。 数字可以细分为浮点数和整数,浮点数就是带有小数位的数,但事实上在 JavaScript 只有`64位的浮点数`,具体的范围是 `[-2^53 ~ 2^53]`,整数也使用浮点数表示。 数字类型也存在负数,如果数字的区间为 `(0, 1)`,则可以省略小数点前的 `0`。 var num1 = 5; var num2 = .1; var num3 = 0.5; var num4 = -10; var num5 = 884739573; 以上是数字的一些表示方式。 如果数字的大小超过最大值或者最小值,那他的值在 JavaScript 中会表示为 `Infinity` 和 `-Infinity`。 var base = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999; var num1 = 99999 * base; var num2 = -99999 * base; console.log(num1); // 输出:Infinity console.log(num2); // 输出:-Infinity 这两个值分别表示为`无穷大`和`无穷小`。 JavaScript 中还可以用数字表示`二进制`、`八进制`与`十六进制`。 二进制是以 `0b` 开头的数字。 var val10 = 0b1010; var val8 = 0b1000; console.log(val10); // 输出:10 console.log(val8); // 输出:8 在输出的时候还是会以十进制的结果进行输出。 八进制则可以用 `0` 开头的数字表示。 var val56 = 070; console.log(val56); // 输出:56 十六进制使用 `0x` 开头表示。 var val10 = 0xA; console.log(val10); // 输出:10 十六进制是比较常用的一种方式,二进制和八进制的表示使用相对较少。 ### 2.3 布尔 布尔值表示两种状态,如同使用零和一区分状态的开关一样。  <center>开关</center> 布尔值两种状态对应 `true` 和 `false` 两个值。 通常 `true` 被称为`真值`,`false` 被称为`假值`,两者也被统一称为`布尔值`。 var empty = true; var isVIP = false; 通常在只有两种状态的情况下会使用布尔值。 以下值在转换成布尔值的时候会转换成 `false`。 * null * undefined * NaN * 0 ( 数字 0 ) * 空字符串 ### 2.4 null `null`是一个非常特殊的类型,表示对象的值未设置,也可以简单理解成`空`,`什么都没有`。 通常`null`会在应该获取到一个对象,但是没获取到的时候进行使用,结合对象会更好理解。 在初始化一个变量的时候,有时候类型不确定,或者应该是一个对象,但还有设置值的时候会使用到null。 var obj = null; ### 2.5 undefined `undefined`从中文意思上理解就是不确定或者没有定义。 一个变量在声明后如果没有赋值,他的值就是`undefined`。 var age; console.log(age); // 输出:undefined 一个函数在没有指定返回值的时候,默认就会返回`undefined`。 function fn() { console.log('我是名字为fn的函数'); } var val = fn(); console.log(val); // 输出:undefined 函数`fn`没有提供返回值,但`val`的值为`undefined`。 比较有趣的是,`undefined`既是一种数据类型,在浏览器中又是作为全局变量存在的,也就是`window`对象下的一个属性。 console.log('undefined' in window); // 输出:true 使用`in`关键字可以校验某个对象下是否存在某个属性。这里的意思就是`undefined`属性是否在`window对象`下存在。 控制台会输出布尔值`true`,为一个真值,表示属性是确实存在的。 3\. 引用类型 -------- ### 3.1 函数 函数其实是一段 `JavaScript` 代码,调用函数就会执行函数中的代码。 使用 `function` 关键字就可以定义一个函数,简单的函数语法如下: function 函数名(参数) { 函数体; return 返回值; } var ret = 函数名(参数1) // 调用函数 函数名就是函数的名字,在调用函数的时候会被使用到。 参数则是传递给函数的数据,函数内部可以访问到传进来的参数。 `return` 则标志着函数的结束,返回值会被作为结果进行返回。 function add(arg1, arg2) { var sum = arg1 + arg2; return sum; } var num1 = add(1, 2); var num2 = add(4, 2); console.log(num1); // 输出:3 console.log(num2); // 输出:6 上面这个例子就是声明了一个名为 `add` 的函数,其功能就是把两个参数求和并返回。 可以看到函数让代码更加有 `意义`,调用 `add` 函数的地方可以很好的理解这里是在做求和操作,同时提高了代码的复用率。 ### 3.2 对象 对象由属性和方法组成。 其格式如下: var obj = { 属性名1: 属性值1, 属性名2: 属性值2, 方法名1: 方法1, 方法名2: 方法2, '属性名3': 属性值3, }; 属性名和方法名都为字符串,如果其符合变量命名规范,则可以不使用引号包裹。 本质上方法也可以算作一个属性,通常在对象里一个属性的属性值为一个函数,就会称之为方法。 var obj = { name: '小明', age: 12, say: function() { console.log('我叫' + this.name + ', 我的年龄是' + this.age + '岁'); }, 'father-name': '小蓝', }; console.log(obj.name); // 输出:小明 console.log(obj['father-name']); // 输出:小蓝 obj.say(); // 调用 say 方法,会输出:我叫小明, 我的年龄是12岁 上述例子中的 `obj` 对象具有三个属性(name、age、father-name)一个方法(say)。 属性可以是任意的数据类型,格式为`属性名: 属性值`,多个属性则由`逗号(,)`分隔,方法则只能为一个函数,通常会是一个匿名函数(函数相关的详细内容可以查阅函数章节)。 通过`对象.属性`就可以访问到对象属性的属性值,如果属性名是一个不符合变量命名规范的值,则可以通过`对象['属性名']`进行访问,方法同理,因为本质上方法也是属性。 既然属性可以是任意的数据类型,则也可以是一个对象: var obj = { name: '小明', colors: { hair: 'red', eye: 'blue', skin: 'white', }, }; 理论上在内存允许的情况下,可以进行无限层的对象嵌套。 以上的例子都是采用`字面量`的方式创建一个对象,还有许多种方式可以创建对象。 如使用`Object`构造一个新对象。 var obj = new Object(); obj.name = '小明'; obj.age = 16; obj.colors = { hair: 'red', eye: 'blue', }; console.log(obj.colors.hair); // 输出:red console.log(obj.name); // 输出:小明 obj.name = '小红'; console.log(obj); // 将会在控制台输出 obj 对象 通过 `new Object()` 就可以创建一个新的对象。 通过`对象.属性 = 属性值`的方式就可以设置一个属性和属性值,这一方式遵循以下规则: * 如果要赋值的属性不存在,则会创建这个属性并赋值 * 如果要赋值的属性存在,则会修改这个属性的值 另外还可以使用`构造函数`、`Object.create`等方式创建对象,具体请参考对象章节。 ### 3.3 数组 数组是一组数据构成的列表。 数组由中括号包裹,每一项通过`逗号`进行分隔: var arr = [1, '2', 3, 4, 5]; console.log(arr[0]); // 输出:1 console.log(arr[1]); // 输出:"2" 和对象一样的是,数组的每一项也可以是任意类型的数据。 如果需要访问数组中的每一项可以通过`数组[下标]`的格式进行访问。 下标就是数组每一项的编号,这个编号从`0`开始,第一项为`0`,第二项为`1`,以此类推。 数组可以理解成一种特殊的对象,他原生具有一些方法,如遍历数组: var arr = ['a', 'b', 'c']; arr.forEach(function(item, index) { console.log(item, index); // "a" 0, "b" 1, "c" 2 }); 通过`数组.forEach`的方式就可以遍历数组,`forEach`方法接受一个函数,这个函数在遍历到每一项的时候会被调用,并将每一项的值和下标作为参数传递过来。 既然具有一些方法,同样的也具有一些属性,最常用的就是`length`属性: var arr = [1, 2, 3]; console.log(arr.length); // 输出:3 数组的 `length` 属性会返回数组的长度。 4\. 值类型和引用类型的区分方式 ----------------- 从内存角度出发,值类型放在内存栈中,引用类型则放在内存堆中。 引用类型的数据长度是不固定的,如对象所占用的空间很大一部分由属性值决定,而属性值又可以是任意类型。 另外最大的区别就如分类名一样,引用类型的数据本身是指向内存上的一块地址,操作的时候对地址上的值进行操作。 而值类型直接操作值,不论是复制或是修改都是直接产生一个新的值。 var obj1 = { name: '小明', }; var obj2 = obj1; obj2.name = '小红'; console.log(obj1.name); // 输出:小红 var val1 = 1; var val2 = val1; val2 = 2; console.log(val1); // 输出:1 通过上面的例子就可以看出引用类型和值类型在 JavaScript 程序中的区别。 引用类型在进行复制的时候,其实就是多了一个引用,操作的值是同一个。 而值类型进行复制后,则是一个新的值。 5\. 小结 ------ 1. 数据类型是比较重要的一个概念,在分类上分为引用类型和值类型。 2. 值类型包括:字符串、数字、布尔、null、undefined。 3. 引用类型包括:函数、对象、数组。 4. 引用类型相对复杂,每一种类型也具有很多特性,其内容可以参阅对应的章节。
上一篇:
JavaScript 变量
下一篇:
JavaScript if 语句
该分类下的相关小册推荐:
深入浅出Go语言核心编程(二)
Golang并发编程实战
深入浅出Go语言核心编程(四)
Go开发权威指南(上)
Go Web编程(上)
深入浅出Go语言核心编程(七)
go编程权威指南(三)
深入浅出Go语言核心编程(五)
Go-Web编程实战
深入浅出Go语言核心编程(八)
Go语言入门实战经典
WebRTC音视频开发实战