数据类型
分类
- 基本(值)类型
- Number ----- 任意数值 -------- typeof
- String ----- 任意字符串 ------ typeof
- Boolean ---- true/false ----- typeof
- undefined --- undefined ----- typeof/===
- null -------- null ---------- ===
- 对象(引用)类型
- Object ----- 任意对象([]、函数...)----- typeof/instanceof
- Array ------ 特别的对象类型(数值下标 / 内部数据有序) ----- instanceof
- Function ---- 特别的对象类型(可执行) ----- typeof
判断
- typeof
- 返回数据类型的字符串表达;
var a;
console.log(typeof a===underfined) //false
console.log(typeof a==='underfined') //true
-
可以区别:数值、字符串、布尔值、undefined、function;
-
不能区别:null与object、一般object与array。——全部返回 'object'
-
instanceof
-
专门用来判断对象数据的类型:Object、Array与Function。
-
-
===
- 仅可以判断:undefined和null。
相关问题
1. undefined与null的区别?
undefined代表定义未赋值;null定义并赋值,只是值为null。
2. 什么时候给变量赋值为null呢?
-
初始化赋值:将要作为引用变量使用, 但对象还没有确定。
var a = null // a将指向一个对象,但对象此时还没有确定
-
结束时赋值:将变量指向的对象成为垃圾对象(被垃圾回收器回收)。
a = null // 让a指向的对象成为垃圾对象
3. 严格区别变量类型与数据类型?
js的变量本身是没有类型的,变量的类型实际上是变量内存中数据的类型(js是弱类型的语言)。var a; 判断变量类型,实际上 是判断值的类型。
数据的类型(数据对象):
- 基本类型
- 对象类型
变量的类型(变量内存值的类型):
- 基本类型:保存基本类型的数据(保存基本类型数据的变量)。
- 引用类型:保存对象地址值(保存对象地址值的变量)
数据,变量, 内存的理解
什么是数据?
- 在内存中可读的, 可传递的保存了特定信息的'东东',本质上是0101...
- 数据的特点:具有可读、可传递、可运算的基本特性。
- 一切皆数据, 函数也是数据
- 在内存中的所有操作的目标: 数据
什么是内存?
- 内存条通电后产生的存储空间(临时的)
- 内存产生和死亡: 内存条(集成电路板)==>通电==>产生一定容量的存储(内存)空间==>存储各种数据==>处理数据==>断电==>内存和数据全部消失
- 内存的空间是临时的, 而硬盘的空间是持久的
- 分配内存: 声明变量和函数或创建对象时, JS引擎会自动为此分配一定大小的内存来存放对应的数据
- 释放内存: 清空内存中的数据, 标识内存可以再分配使用(内存不释放就不能复用)
- 自动释放: 栈空间的局部变量 (全局变量-运行结束后释放,局部变量-函数执行完毕后释放)
- 垃圾回调器回调: 堆空间的垃圾对象
- 一块内存包含2个方面的数据
- 内部存储的数据
- 地址值数据
- 内存空间的分类
- 栈空间: 全局变量和局部变量(空间较小)
- 堆空间: 对象(空间较大)
什么是变量?
找变量,找不到会报错。找属性,找不但返回undefined
- 值可以变化的量,由变量名与变量值组成。
- 一个变量对应一块小内存,变量名用来查找对应的内存,变量值就是内存中保存的内容。
三者之间的关系
- 内存是容器, 用来存储不同数据
- 变量是内存的标识, 通过变量我们可以操作(读/写)内存中的数据
相关问题
1.关于赋值与内存的问题?
var a = xxx(赋值操作),a内存中到底保存的是什么?
-
xxx是一个基本数据,保存的就是这个数据。
var a=120; var b='haha' -
xxx是一个对象,保存的是对象的地址值。
var c={}; var d=function(){ }; -
xxx是一个变量,保存的xxx的内存内容(保存的可能是基本数据,也可能是地址值数据)。
var e=a; //e=120 var f=c; //f={}的地址值
2.关于引用变量赋值问题
-
2个引用变量指向同一个对象(保存的内容是同一个对象的地址值),通过一个引用变量修改对象内部数据,另一个引用变量也看得见(看见的是修改之后的数据)。
-
2个引用变量指向同一个对象,让一个引用变量指向另一个对象,另一个引用变量还是指向原来的对象。(有细节!!!)
3.关于数据传递问题
在js调用函数时传递变量参数时,是值传递还是引用传递?
-
理解1:都是值(基本/地址值)传递。
-
理解2:可能是值传递,也可能是引用传递(地址值)。
-
只有值传递,没有引用传递,传递的都是变量的值,只是这个值可能是基本数据,也可能是地址(引用)数据。
-
如果后一种看成是引用传递,那就值传递和引用传递都可以有。
4.JS引擎如何管理内存?
- 内存生命周期
- 分配小内存空间,得到它的使用权(分配需要的内存)。
- 存储数据,可以反复进行操作(使用分配到的内存)。
- 释放小内存空间(不需要时将其释放/归还)。
- 释放内存
-
局部变量:函数执行完 自动释放(为执行函数分配的栈空间内存)。
-
对象:成为垃圾对象==>垃圾回收器回收(存储对象的堆空间内存:当内存没有引用指向时,对象成为垃圾对象,垃圾回收器后面就会回收释放此内存。
-
对象的理解和使用
什么是对象?
- 多个数据(属性)的集合
- 用来保存多个数据(属性)的容器
- 一个对象代表现实中的一个事物(代表现实中的某个事物,是该事物在编程中的抽象)。
为什么要用对象?
- 便于对多个数据进行统一管理。
对象的组成
-
属性:属性名(字符串)和属性值(任意)组成。(代表现实事物的状态数据)
-
属性组成:
- 属性名 : 字符串(标识)
- 属性值 : 任意类型
-
-
方法:一种特别的属性(属性值是函数)。(代表现实事物的行为数据)
-
特别的对象
- 数组: 属性名是0,1,2,3之类的索引
- 函数: 可以执行的
如何访问对象内部数据?
-
.属性名:编码简单,但有时不能用
-
['属性名']:编码麻烦,但通用
什么时候必须使用['属性名']的方式?
-
属性名包含特殊字符:-、空格(属性名不是合法的标识名)。
-
属性名不确定。
函数的理解和使用
什么是函数?
- 用来实现特定功能的, n条语句的封装体
- 只有函数类型的数据是可以执行的, 其它的都不可以
- 函数也是对象。
-
fn instanceof Object===true
-
函数有属性: prototype
-
函数有方法: call()/apply()
-
可以添加新的属性/方法
-
为什么要用函数?
- 提高复用性
- 便于阅读交流
如何定义函数?
-
函数声明:整体会被提升到当前作用域顶部。
-
表达式:也会提升到顶部,但是只有变量名提升。
如何调用(执行)函数?
- test():一般函数直接调用
- obj.test():通过对象调用
- new test():构造函数通过new 调用
- test.call/apply(obj):临时让test成为obj的方法进行调用
回调函数的理解
- 什么函数才是回调函数?
- 你定义的
- 你没有调用
- 但它最终执行了(在一定条件下或某个时刻)
- 常用的回调函数
-
dom事件回调函数==> this是发生事件的dom元素
-
定时器回调函数==> this是window
- 超时定时器
- 循环定时器
-
ajax请求回调函数(后面讲解)
-
生命周期回调函数(后面讲解)
-
立即执行函数
1. 理解
- 全称:Immediately-Invoked Function Expression,立即调用函数表达式
- 别名:匿名函数自调用
(function(w, obj){ //实现代码 })(window, obj)
2. 作用
- 隐藏内部实现
- 不会污染外部(全局)命名空间
- 用它来编码js模块
函数中的this
this是什么?
-
任何函数本质上都是通过某个对象来调用的,如果没有直接指定就是window。
-
所有函数内部都有一个变量this。
-
它的值是调用函数的当前对象。
-
一个关键字,一个内置的引用变量;
-
在函数中都可以直接使用this;
-
this代表调用函数的当前对象;
-
在定义函数时,this还没有确定,只有在执行时才动态确定(绑定)的。
-
-
根据 调用函数的方式 不同,this会指向不同的对象:
1.以函数的形式调用时,this是window
2.以方法的形式调用时,this就是调用方法的对象
3.以构造函数的形式调用时,this就是新创建的对象
4.使用call和apply调用时,this是指定的那个对象
5.在全局作用域中this代表window
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>07_函数中的this</title>
</head>
<body>
<script type="text/javascript">
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
var p = new Person("yello"); //this是谁? p
p.getColor(); //this是谁? p
var obj = {};
p.setColor.call(obj, "black"); //this是谁? obj 让setColor方法成为obj对象的方法进行调用
var test = p.setColor;
test(); //this是谁? window
function fun1() {
function fun2() {
console.log(this);
}
fun2(); //this是谁? window
}
fun1();
</script>
</body>
</html>
如何确定this的值?
test():window
p.test():p
new test():新创建的对象
p.call(obj):obj
前置知识:本质上任何函数在执行时都是通过某个对象调用的。