JS高级基础回顾

JS高级基础回顾

JS基础回顾

数据类型相关知识

JS基础 - Hexo (mk310.github.io)

数据变量内存

什么是数据

  1. 存储在内存中代表特定信息的’东西’, 本质上是0101…
  2. 数据的特点: 可传递, 可运算 –>let a=0;b=a 🔜体现可传递
  3. 一切皆数据
  4. 内存中所有操作的目标: 数据
  • 算术运算
  • 逻辑运算
  • 赋值
  • 运行函数

什么是内存?

  1. 内存条通电后产生的可储存数据的空间(临时的)

image-20210630191828124

  1. 内存产生和死亡: 内存条(电路版)==>通电==>产生内存空间==>存储数据==>处理数据==>断电==>内存空间和数据都消失
  2. 一块小内存的2个数据
  • 内部存储的数据
  • 地址值
  1. 内存分类
  • 栈: 全局变量/局部变量
  • 堆: 对象
  • image-20210630192130518

什么是变量?

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

ps:变量obj.xx–>.相当于拿着地址找到后面对应的内存,所以只有当我变量中存的是地址,才可以用.

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

相关问题

赋值和内存的问题:

var a = xxx,a内存中保存的是什么

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

变量赋值问题:

  • 两个引用变量指向同一个对象,通过一个变量修改对象内部数据,另一个变量得到也是修改后数据

值传递还是引用传递:

调用函数传递变量参数时候:

  • 理解1:都是值传递(基本数据和地址值都是值)
  • 理解2:基本数据是值传递,引用数据是引用传递

JS管理内存:

  1. 内存生命周期

    1. 分配小内存空间,得到使用权
    2. 存储数据,反复使用
    3. 释放小内存
  2. 释放内存

    1. 局部变量:函数执行完自动释放
    2. 对象:成为垃圾对象后=>垃圾回收器回收
    1
    2
    3
    4
    5
    6
    7
    8
    var a = 3

    var obj = {name:'test'}

    obj = undefined||null //此时obj没有被释放,之前创建的{name:'test'},没有地址指向它,成为垃圾对象,在之后某个时刻会被垃圾回回收

    function fn() {var b={}}
    fn() //在函数执行后,b无法访问成为垃圾对象,程序完成后的某个时间被垃圾回收

对象

对象的概念

  1. 什么是对象
    1. 多个数据封装体
    2. 用来保存多个数据的容器
    3. 一个对象代表现实世界中的一个食物
  2. 为什么使用对象
    1. 统一管理多个数据
  3. 对象组成
    1. 属性构成:属性名(字符串),属性值(任意)
    2. 方法:一种特殊的属性:(属性值是函数)

如何访问对象内部数据

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

什么时候使用['属性名']:

  • 属性名含有特殊字符-``空格
  • 属性名不确定时候
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
示例代码:
var p = []
p.content type = 'test' //报错
p.content-type = 'test' //报错

p['content-type'] = 'test' //成功

//属性名不确定
var proName = 'myAge' //proName存储变化的变量名称
var value = 18

// p.proName = value //ReferenceError: proname is not defined

p[proName] = value

console.log(p[proName])

函数

函数的概念

什么是函数:

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

为什么要用函数:

  • 提高代码复用
  • 便于阅读交流

如何定义函数:

  • 函数声明
  • 表达式 //TODO:
1
2
function fn1(){fonsole.log('fn1')} //函数声明
const fn2 = () =>console.log('fn2') //表达式

调用(执行)函数

  1. functionName()直接调用
  2. obj.functionName()通过对象调用
  3. new functionName()new调用
  4. functionName.call/apply(obj)临时让functionName()成为obj的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//    定义一个函数
function functionName(){
console.log('函数已经执行')


}

// 调用
// 1.直接调用
functionName()

// 2.通过对象调用
var obj = {
functionName : function (){
console.log('函数已经执行')
}
}
obj.functionName()

// 3.new调用
new functionName();

// 4.call调用
functionName.call(obj)

回调函数

什么函数是回调函数

  • 自己定义的
  • 自己没有调用
  • 最终程序执行的

常见的回调函数

  • dom时间回调函数==>发生事件的dom元素
  • 定时器回调函数==>window
  • ajax请求回调函数//TODO
  • 生命周期回调函数//TODO
1
2
3
4
// dom事件回调函数
document.getElementById('btn').onclick = function(){alert('hell')}
// 定时器回调函数
setTimeout(function(){alert('定时器'+this)},2000)

IIFE(自调用函数)

Immediately-Invoked Function Expression(IIFE)

作用:

  • 隐藏实现的细节
  • 不会污染全局命名空间
  • 用来编码js模块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 (function () { //匿名函数自调用
var a = 3
console.log(a + 3)
})()
console.log(a) // a is not defined

//此处前方为何要一个`;`-->因为自调用函数外部有一个()包裹,可能与前方以()结尾的代码被一起认为是函数调用
//不加分号可能会被认为这样 console.log(a)(IIFE)
;(function () {//不会污染外部(全局)命名空间-->举例
let a = 1;
function test () { console.log(++a) } //声明一个局部函数test
window.$ = function () { return {test: test} }// 向外暴露一个全局函数
})()
test () //test is not defined
$().test() // 1. $是一个函数 2. $执行后返回的是一个对象

函数中的this

this是什么

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

如何确定this的值

  • test(): window
  • p.test(): p
  • new test(): 新创建的对象
  • p.call(obj): obj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 function Person(color) {
console.log(this)
this.color = color;
this.getColor = function () {
console.log(this)
return this.color;
};
this.setColor = function (color) {
console.log(this)
this.color = color;
};
}

Person("red"); //this是谁? window

const p = new Person("yello"); //this是谁? p

p.getColor(); //this是谁? p

const obj = {};
//调用call会改变this指向-->让我的p函数成为`obj`的临时方法进行调用
p.setColor.call(obj, "black"); //this是谁? obj

const test = p.setColor;
test(); //this是谁? window -->因为直接调用了

function fun1() {
function fun2() { console.log(this); }
fun2(); //this是谁? window
}
fun1();//调用fun1

关于语句分号

  1. js一条语句的后面可以不加分号
  2. 是否加分号是编码风格问题, 没有应该不应该,只有你自己喜欢不喜欢
  3. 在下面2种情况下不加分号会有问题
  • 小括号开头的前一条语句
  • 中方括号开头的前一条语句
  1. 解决办法: 在行首加分号
  2. 强有力的例子: vue.js库
  3. 知乎热议: https://www.zhihu.com/question/20298345