基础总结深入
- 什么是数据?
- 存储在内存中代表特定信息的’东东’, 本质上是0101…
- 数据的特点: 可传递, 可运算
- 一切皆数据
- 内存中所有操作的目标: 数据
- 算术运算
- 逻辑运算
- 赋值
- 运行函数
- 什么是内存?
- 内存条通电后产生的可储存数据的空间(临时的)
- 内存产生和死亡: 内存条(电路版)通电>产生内存空间==>存储数据==>处理数据==>断电==>内存空间和数据都消失
- 一块小内存的2个数据
- 内部存储的数据
- 地址值
- 内存分类
- 栈: 全局变量/局部变量
- 堆: 对象
- 什么是变量?
- 可变化的量, 由变量名和变量值组成
- 每个变量都对应的一块小内存, 变量名用来查找对应的内存, 变量值就是内存中保存的数据
- 内存,数据, 变量三者之间的关系
- 内存用来存储数据的空间
- 变量是内存的标识
相关问题解决
- undefined与null的区别?
- undefined代表定义未赋值
- nulll定义并赋值了, 只是值为null
let a;
console.log(a) // undefined
a = null;
console.log(a) // null
- 什么时候给变量赋值为null呢?
- 初始赋值, 表明将要赋值为对象
- 结束前, 让对象成为垃圾对象(被垃圾回收器回收)
//起始
let b = null; // 初始赋值为null, 表明将要赋值为对象
//确定对象就赋值
b = ['adas', 12];
//最后
b = null; // 让b指向的对象成为垃圾对象(被垃圾回收器回收)
// b = 2;
let c = function () {
}
console.log(typeof c); // 'function'
- 严格区别变量类型与数据类型?
- 数据的类型
- 基本类型
- 对象类型
- 变量的类型(
变量内存值的类型
)- 基本类型:
保存就是基本类型的数据
- 引用类型:
保存的是地址值
(在栈中)
- 基本类型:
- 问题: let a = xxx, a内存中到底保存的是什么?
- xxx是基本数据, 保存的就是这个数据
- xxx是对象, 保存的是对象的地址值
- xxx是一个变量, 保存的xxx的内存内容(可能是基本数据, 也可能是地址值)
- 关于引用变量赋值问题
- 2个引用变量指向同一个对象, 通过一个变量修改对象内部数据, 另一个变量看到的是修改之后的数据
- 2个引用变量指向同一个对象, 让其中一个引用变量指向另一个对象, 另一引用变量依然指向前一个对象
<script>
let obj1 = {
name: 'Tom'
};
let obj2 = obj1;
obj2.age = 12;
console.log(obj1.age); // 12
function fn(obj) {
obj.name = 'A';
}
fn(obj1)
console.log(obj2.name) //A
let a = {
age: 12
}
let b = a;
a = {
name: 'BOB',
age: 13
}
b.age = 14
console.log(b.age, a.name, a.age) // 14 Bob 13
function fn2(obj) {
obj = {
age: 15
}
}
fn2(a)
console.log(a.age)
</script>
- 在js调用函数时传递变量参数时, 是值传递还是引用传递
- 理解1: 都是值(基本/地址值)传递
- 理解2: 可能是值传递, 也可能是引用传递(地址值)
<script>
let a = 3;
function fn(a) {
a = a + 1;
}
fn(a);
console.log(a);
function fn2(obj) {
console.log(obj.name);
}
let obj = {
name: 'Tom'
}
fn2(obj);
</script>
对象
- 什么是对象?
(what)
- 多个数据的封装体
- 用来保存多个数据的容器
- 一个对象代表现实中的一个事物
- 为什么要用对象?
(why)
- 统一管理多个数据
- 对象的组成
- 属性: 属性名(字符串)和属性值(任意)组成
- 方法: 一种特别的属性(属性值是函数)
- 如何访问对象内部数据?
(how)
- .属性名: 编码简单, 有时不能用
- [‘属性名’]: 编码麻烦, 能通用
- 什么时候必须使用
['属性名']
的方式?
- 属性名包含特殊字符:
-
空格
- 属性名不确定
<script>
let p = {};
//1. 给p对象添加一个属性: content type: text/json
// p.content-type = 'text/json' ;//不能用
p['content-type'] = 'text/json';
console.log(p['content-type']);
//2. 属性名不确定
let propName = 'myAge';
let value = 18;
// p.propName = value ;//不能用
p[propName] = value;//undefined
console.log(p[propName]);//18
</script>
函数
- 什么是函数?
(what)
- 实现特定功能的n条语句的封装体
- 只有函数是可以执行的, 其它类型的数据不能执行
- 为什么要用函数?
(why)
- 提高代码复用
- 便于阅读交流
- 如何定义函数?
(how)
- 函数声明
- 表达式
- 如何调用(执行)函数?
(how)
- test():
直接调用
- obj.test():
通过对象调用
- new test():
new调用
- test.call/apply(obj):
临时让test成为obj的方法进行调用
回调函数
- 什么函数才是回调函数?
1). 你定义的
2). 你没有调
3). 但最终它执行了(在某个时刻或某个条件下) - 常见的回调函数?
- dom事件回调函数 ==>发生事件的dom元素
- 定时器回调函数 ===>window
- ajax请求回调函数
- 生命周期回调函数
document.getElementById('btn').onclick = function () { // dom事件回调函数
alert(this.innerHTML)
}
//定时器
// 超时定时器
// 循环定时器
setTimeout(function () { // 定时器回调函数
alert('到点了'+this)
}, 2000);
IIFE(Immediately-Invoked Function Expression)
立即调用的函数表达式
作用
- 隐藏实现
- 不会污染外部(全局)命名空间
- 用它来编码js模块
<script>
(function () { //匿名函数自调用
let a = 3
console.log(a + 3);//6
})();
let a = 4;
console.log(a);//4
(function () {
let a = 1
function test () {
console.log(++a);//2
};
window.$ = function () { // 向外暴露一个全局函数
return {
test: test
}
}
})();
$().test() // 1. $是一个函数 2. $执行后返回的是一个对象
</script>
函数中的this
- this是什么?
- 任何函数本质上都是通过某个对象来调用的,如果没有直接指定就是window
- 所有函数内部都有一个变量this
- 它的值是调用函数的当前对象
- 如何确定this的值?
- test(): window
- p.test(): p
- new test(): 新创建的对象
- p.call(obj): obj
<script>
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
let p = new Person("yello"); //this是谁? p
p.getColor(); //this是谁? p
let obj = {};
p.setColor.call(obj, "black"); //this是谁? obj
let test = p.setColor;
test(); //this是谁? window
function fun1() {
function fun2() {
console.log(this);
}
fun2(); //this是谁? window
}
fun1();
</script>