数据类型的分类和判断

1、分类

  • 基本(值)类型

    • String: 任意字符串
    • Number: 任意的数字
    • boolean: true/false
    • undefined: undefined
    • null: null
  • 对象(引用)类型

    • Object: 任意对象
    • Function: 一种特别的对象(可以执行)
    • Array: 一种特别的对象(数值下标, 内部数据是有序的)

2、判断

  • typeof:返回数据类型的字符串表达

    • 可以判断: undefined/ 数值 / 字符串 / 布尔值 / function
    • 不能判断: null与object object与array
  • instanceof:

    • 判断对象的具体类型
  • ===

    • 可以判断: undefined, null
  1. //1. 基本
  2. // typeof返回数据类型的字符串表达
  3. var a
  4. console.log(a, typeof a, typeof a==='undefined',a===undefined ) // undefined 'undefined' true true
  5. console.log(undefined==='undefined') //flase
  6. a = 4
  7. console.log(typeof a==='number')
  8. a = 'atguigu'
  9. console.log(typeof a==='string')
  10. a = true
  11. console.log(typeof a==='boolean')
  12. a = null
  13. console.log(typeof a, a===null) // 'object'
  14. console.log('-----------------')
  15. //2. 对象
  16. var b1 = {
  17. b2: [1, 'abc', console.log],
  18. b3: function () {
  19. console.log('b3')
  20. return function () {
  21. return 'xfzhang'
  22. }
  23. }
  24. }
  25. console.log(b1 instanceof Object, b1 instanceof Array) // true false
  26. console.log(b1.b2 instanceof Array, b1.b2 instanceof Object) // true true
  27. console.log(b1.b3 instanceof Function, b1.b3 instanceof Object) // true true
  28. console.log(typeof b1.b2, '-------') // 'object'
  29. console.log(typeof b1.b3==='function') // true
  30. console.log(typeof b1.b2[2]==='function')
  31. b1.b2[2](4)
  32. console.log(b1.b3()())

01_基础总结深入 - 图1

常见问题

1、undefined与null的区别?

  • undefined代表定义未赋值
  • nulll定义并赋值了, 只是值为null
  1. var a
  2. console.log(a) // undefined
  3. a = null
  4. console.log(a) // null

2、什么时候给变量赋值为null呢?

  • 初始赋值, 表明将要赋值为对象
  • 结束前, 让对象成为垃圾对象(被垃圾回收器回收)
  1. //起始
  2. var b = null // 初始赋值为null, 表明将要赋值为对象
  3. //确定对象就赋值
  4. b = ['atguigu', 12]
  5. //最后
  6. b = null // 让b指向的对象成为垃圾对象(被垃圾回收器回收)
  7. // b = 2

3、严格区别变量类型与数据类型?

  • 数据的类型

    • 基本类型
    • 对象类型
  • 变量的类型(变量内存值的类型)

    • 基本类型: 保存就是基本类型的数据
    • 引用类型: 保存的是地址值

数据,变量, 内存的理解

1、什么是数据?

  • 存储在内存中代表特定信息的’东东’, 本质上是0101…
  • 数据的特点: 可传递, 可运算
  • 一切皆数据
  • 内存中所有操作的目标: 数据

    • 算术运算
    • 逻辑运算
    • 赋值
    • 运行函数

2、什么是内存?

  • 内存条通电后产生的可储存数据的空间(临时的)
  • 内存产生和死亡: 内存条(电路版)>通电>产生内存空间==>存储数据==>处理数据==>断电==>内存空间和数据都消失
  • 一块小内存的2个数据

    • 内部存储的数据
    • 地址值
  • 内存分类

    • 栈: 全局变量/局部变量
    • 堆: 对象

3、什么是变量?

  • 可变化的量, 由变量名和变量值组成
  • 每个变量都对应的一块小内存, 变量名用来查找对应的内存, 变量值就是内存中保存的数据

4、内存,数据, 变量三者之间的关系

  • 内存用来存储数据的空间
  • 变量是内存的标识

常见问题

问题:var a = xxx, a内存中到底保存的是什么?

  • xxx是基本数据, 保存的就是这个数据
  • xxx是对象, 保存的是对象的地址值
  • xxx是一个变量, 保存的xxx的内存内容(可能是基本数据, 也可能是地址值)

关于引用变量赋值问题

  • 2个引用变量指向同一个对象, 通过一个变量修改对象内部数据, 另一个变量看到的是修改之后的数据
  • 2个引用变量指向同一个对象, 让其中一个引用变量指向另一个对象, 另一引用变量依然指向前一个对象
  1. <script type="text/javascript">
  2. var obj1 = {name: 'Tom'}
  3. var obj2 = obj1
  4. obj2.age = 12
  5. console.log(obj1.age) // 12
  6. function fn (obj) {
  7. obj.name = 'A'
  8. }
  9. fn(obj1)
  10. console.log(obj2.name) //A
  11. var a = {age: 12}
  12. var b = a
  13. a = {name: 'BOB', age: 13} //这时候a指向另一个对象了,b仍然指向前一个对象,ab没有关系了
  14. b.age = 14
  15. console.log(b.age, a.name, a.age) // 14 Bob 13
  16. function fn2 (obj) {
  17. obj = {age: 15}
  18. }
  19. fn2(a)
  20. console.log(a.age) //是13不是15
  21. </script>

问题: 在js调用函数时传递变量参数时, 是值传递还是引用传递

  • 理解1: 都是值(基本/地址值)传递
  • 理解2: 可能是值传递, 也可能是引用传递(地址值)

问题: JS引擎如何管理内存?

  1. 内存生命周期
  • 分配小内存空间, 得到它的使用权
  • 存储数据, 可以反复进行操作
  • 释放小内存空间
  1. 释放内存
  • 局部变量: 函数执行完自动释放
  • 对象: 成为垃圾对象==>垃圾回收器回收
  1. <script type="text/javascript">
  2. var a = 3
  3. var obj = {}
  4. obj = undefined
  5. function fn () {
  6. var b = {}
  7. }
  8. fn() // b是自动释放, b所指向的对象是在后面的某个时刻由垃圾回收器回收
  9. </script>

对象的理解和使用

1、什么是对象?

  • 多个数据的封装体
  • 用来保存多个数据的容器
  • 一个对象代表现实中的一个事物

2、为什么要用对象?

  • 统一管理多个数据

3、对象的组成

  • 属性: 属性名(字符串)和属性值(任意)组成
  • 方法: 一种特别的属性(属性值是函数)
  1. <script type="text/javascript">
  2. var p = {
  3. name: 'Tom',
  4. age: 12,
  5. setName: function (name) {
  6. this.name = name
  7. },
  8. setAge: function (age) {
  9. this.age = age
  10. }
  11. }
  12. p.setName('Bob')
  13. p['setAge'](23)
  14. console.log(p.name, p['age'])
  15. /*
  16. p.setName输出的是一个函数,即
  17. function (name) {
  18. this.name = name
  19. }
  20. p.setName("bob")//加上括号之后就是调用函数
  21. */
  22. </script>

4、如何访问对象内部数据?

  • .属性名 :编码简单,有时不能用
  • ['属性名'] :编码麻烦,能通用

问题1:什么时候必须使用['属性名']的方式?

  1. 属性名包含特殊字符: - 空格
  2. 属性名不确定,通过变量传递
  1. <script type="text/javascript">
  2. var p = {}
  3. //1. 给p对象添加一个属性: content type: text/json
  4. // p.content-type = 'text/json' //不能用
  5. p['content-type'] = 'text/json'
  6. console.log(p['content-type'])
  7. //2. 变量名不确定
  8. var propName = 'myAge'
  9. var value = 18
  10. // p.propName = value //不能用
  11. p[propName] = value
  12. console.log(p[propName])
  13. </script>

问题2:在js中用中括号访问对象的时候属性为什么要加上双引号?

首先声明一个对象 属性名加不加双引号都是可以的。
var obj = {name1: “张三”}
console.log(obj.name1) // 张三 用点语法 访问 没问题
console.log(obj[name1]) // 直接报 ReferenceError: name1 is not defined

不加双引号的话,js会认为这是变量名,而这个变量是不存在的,所以报“not defined”(未定义)的错误。
而这其实就是用中括号来访问对象属性的意义所在:可以用变量来代替属性名,比如:
var n = “name1”;
console.log(obj[n]); //obj[n]就相当于obj[“name1”]或obj.name1
而用点语法的话属性名是不能用变量的!

函数的理解和使用

函数的基本概念

1、什么是函数?

  • 用来实现特定功能的, n条语句的封装体
  • 只有函数类型的数据是可以执行的, 其它的都不可以

2、为什么要用函数?

  • 提高复用性
  • 便于阅读交流

3、函数也是对象

  • instanceof Object===true
  • 函数有属性: prototype
  • 函数有方法: call()/apply()
  • 可以添加新的属性/方法

函数的3种不同角色

  • 一般函数 : 直接调用
  • 构造函数 : 通过new调用
  • 对象 : 通过.调用内部的属性/方法

、如何定义函数?

  • 函数声明
  • 表达式
  1. function fn1() { //函数声明
  2. console.log('fn1()')
  3. }
  4. var fn2 = function () { //表达式
  5. console.log('fn2()')
  6. }

7、如何调用(执行)函数?

  • test(): 直接调用
  • obj.test(): 通过对象调用
  • new test(): new调用
  • test.call/apply(obj): 临时让test成为obj的方法进行调用
  1. var obj = {}
  2. function test2() {
  3. this.xxx = 'atguigu'
  4. }
  5. // obj.test2() 不能直接, 根本就没有
  6. test2.call(obj) // obj.test2() // 可以让一个函数成为指定任意对象的方法进行调用
  7. console.log(obj.xxx) //输出'atguigu'
  8. console.log(obj.test2())//报错

回调函数的理解
  • 什么函数才是回调函数?

    • 你定义的
    • 你没有调用
    • 但它最终执行了(在一定条件下或某个时刻)
  • 常用的回调函数

    • dom事件回调函数
    • 定时器回调函数
    • ajax请求回调函数(后面讲解)
    • 生命周期回调函数(后面讲解)
  1. document.getElementById('btn').onclick = function () { // dom事件回调函数
  2. alert(this.innerHTML)
  3. }
  4. //定时器
  5. // 超时定时器
  6. // 循环定时器
  7. setTimeout(function () { // 定时器回调函数
  8. alert('到点了'+this)
  9. }, 2000)
  10. /*这两个方法我没有调用,但是他执行了*/

IIFE (Immediately Invoked Function Expression) 立即调用函数表达式

匿名函数自调用:

  1. (function(w, obj){
  2. //实现代码
  3. })(window, obj)

作用

  • 隐藏实现
  • 不会污染外部(全局)命名空间
  • 用它来编码js模块
  1. (function () { //匿名函数自调用
  2. var a = 3
  3. console.log(a + 3)//6
  4. })()
  5. var a = 4
  6. console.log(a);//4
  1. (function () {
  2. var a = 1
  3. function test2() {
  4. console.log(++a)
  5. }
  6. window.$ = function () { // 向外暴露一个全局函数
  7. return {//函数返回一个对象
  8. test: test2//test属性名,test2属性值
  9. }
  10. }
  11. })()
  12. $().test() // 1. $是一个函数 2. $执行后返回的是一个对象
  13. //

函数中的this

1、this是什么?

  • 任何函数本质上都是通过某个对象来调用的,如果没有直接指定就是window
  • 所有函数内部都有一个变量this
  • 它的值是调用函数的当前对象

2、如何确定this的值?

  • test(): window
  • p.test(): p
  • new test(): 新创建的对象
  • p.call(obj): obj

3、

  • 显式指定谁: obj.xxx()
  • 通过call/apply指定谁调用: xxx.call(obj)
  • 不指定谁调用: xxx() : window
  • 回调函数: 看背后是通过谁来调用的: window/其它
  1. function Person(color) {
  2. console.log(this)
  3. this.color = color;
  4. this.getColor = function () {
  5. console.log(this)
  6. return this.color;
  7. };
  8. this.setColor = function (color) {
  9. console.log(this)
  10. this.color = color;
  11. };
  12. }
  13. Person("red"); //this是谁? window
  14. console.log(",,,,,")
  15. var p = new Person("yello"); //this是谁? Person
  16. p.getColor(); //this是谁? p
  17. var obj = {};
  18. p.setColor.call(obj, "black"); //this是谁? obj
  19. var test = p.setColor;
  20. test(); //this是谁? window
  21. console.log(",,,,,")
  22. function fun1() {
  23. function fun2() {
  24. console.log(this);
  25. }
  26. fun2(); //this是谁? window
  27. }
  28. console.log(",,,,,")
  29. fun1();

分号问题

js一条语句的后面可以不加分号

是否加分号是编码风格问题, 没有应该不应该,只有你自己喜欢不喜欢

在下面2种情况下不加分号会有问题

  • 小括号开头的前一条语句
  • 中方括号开头的前一条语句

强有力的例子: vue.js库

  1. var a = 3
  2. ;(function () {
  3. })()
  4. /*
  5. 错误理解
  6. var a = 3(function () {
  7. })();
  8. */
  9. var b = 4
  10. ;[1, 3].forEach(function () {
  11. })
  12. /*
  13. 错误理解
  14. var b = 4[3].forEach(function () {
  15. })
  16. */