JavaScript
基础
数据类型
基本(值)类型
String : 任意字符串
Number: 任意数字
boolean: true/false
undefied :任意数字
null:null
Symbol
let s = Symbol();
typeof s // "symbol"
对象(引用)类型
Object: 任意对象
Function: 一种特别的对象(可执行)
Array:一种特别的对象(数值下标,内部数据是有序的)
判断数据类型
typeof
返回数据类型的字符串表达
可以判断undefined、数值、字符串、布尔值
不能判断 null与object object和array
var a
cosole.log(a) // undefined
cosole.log(typeof a) // 'undefined'
cosole.log(typeof a==='undefined') // true
cosole.log(typeof a===undefined) // true
instanceof
判断对象类型
var b1 = {
b2:[1,'2'],
b3:function () {
console.log(b3)
}
}
//b1是不是object上的实例
b1 instanceof object // true
===
可以判断undefined、null
数据类型相关问题
undefined与null的区别
- undefined代表定义未赋值
- null定义了值,值为null
什么时候给变量赋值为null
- 初始赋值为null,表明赋值为对象
- 结束前,让对象成为垃圾对象(被垃圾回收器回收)
严格区别变量类型和数据类型
变量类型(变量内存值的类型)
基本类型:保存的就是基本类型的数据
引用类型:保存的是地址值
什么是数据
存储在内存中代表特定信息的,本质上是0101…
特点:可传递,可运算
一切皆数据
算术运算
逻辑运算
赋值
运行函数
什么是内存
内存条通电后产生的可存储数据的空间(临时的)
内存产生和死亡:内存条(电路板)==》通电==》产生内存空间==》存储数据==》处理数据==》断电==》内存空间和数据都消失了
一块小内存有两个数据:内部存储的数据 、 地址值
内存分类
栈:全局变量、局部变量
堆:对象
什么是变量
可变化的量,由变量和变量值组成
每个变量都对应的一块内存,变量名用来查找对应的内存,变量值就是内存中保存的数据
内存,数据,变量三者之间的关系
内存用来存储数据空间
变量是内存的标志
引用变量赋值问题
两个引用变量执行一个对象,通过一个变量修改对象内部数据,另一个变量看到的是修改后的数据
js调用函数时传递变量参数时,是值传递
js引擎如何管理内存
内存生命周期
释放内存
什么是对象
多个数据的封装,用来保存多个数据的容器,一个对象代表现实世界中的一个事物。
为什么要用对象
统一管理多个数据
对象组成
属性:属性名(字符串)和属性值(任意)组成
方法:一种特别的属性(属性值是函数)
如何访问对象内部数据
.属性名
:编码简单,有时候不能用
1.属性名包含特殊字符:-
空格
var p = {
}
//p.content-type = 'text/json'
p['content-type']
2.变量名不确定
var pName = 'my'
var value = 18
//p.pName = value
p['pName']
['属性名']
:编码麻烦,能通用
函数
什么是函数
实现特定功能的n条语句的封装
只有函数是可以执行的,其它类型的数据不能执行
为什么用函数
提高代码复用
便于阅读交流
如何定义函数
函数式声明
function fn1(){
}
函数表达式
var fn2 = function (){
}
如何调用(执行)函数
function test(){
}
直接调用 test()
通过对象调用 obj.test()
new调用 new test()
call/apply()调用 test.call(obj)
test.apply(obj)
临时让test成为obj的方法进行调用
可以让一个函数成为指定任意对象的方法进行调用
什么函数才是回调函数
- 你定义的
- 你没有调用
- 但最终它执行了
常见的回调函数
dom事件回调函数
定时器回调函数
ajax请求回调函数
生命周期回调函数
IIFE
立即执行表达函数
(function () {
//匿名函数自调用
})()
作用:
隐藏实现
不污染外部(全局)命名空间
用来编写js模块
(function() {
var a = 1
function test() {
console.log(++a)
}
window.$ = function () {
//向外暴露一个去阿奴函数
return {
test: test
}
}
})()
$().test()
this是什么?
任何函数本质上都是通过某个对象来调用的,没有指定就是window调
所有函数内部都有一个变量this
它的值调用函数的当前对象
如何确定this的值
加分号
小括号的前一条语句
中括号开头的前一调语句
在首行强行加分号
函数的prototype
每个函数都有一个prototype,它默认指向一个object空对象(即称为:原型对象)
原型对象中有一个属性constructor,它指向函数对象
2.给原型对象添加属性(一般是方法):给实例对象访问
作用:函数的所有实例对象自动拥有原型中的属性(方法)
默认指向一个object空对象(没有我们的属性)
显式原型
每个函数function都有一个prototype, 显式原型(属性)
每一实例对象都有一个__proto__,可称为隐式原型(属性)
对象的隐式原型的值为其对应构造函数的显示原型的值
原型链
访问一个对象的属性时,
先在自身属性中找,找到返回
如果没有再沿着__proto__这条链去找,找到返回
如果最终没有找到,返回undefined
object原型对象的原型是null
1.函数的显示原型指向的对象:默认是空Object对象,但是Object不满足
2.所有函数都是Function是它自身的实例(包括它本身)Function是它自身的实例
2.Object的原型对象是原型链的尽头
变量声明提升
通过var定义(声明)的变量,在定义语句之前就可以访问到
值:undefined
函数声明提升
通过function声明的函数,在之前就可以直接被调用
值:函数定义(对象)
变量提升和函数提升是如何产生的
全局执行上下文
- 在执行全局代码前将window确定为全局执行上下文
- 对全局数据进行预处理
var定义的全局变量 undefined,添加为window的属性
function声明的全局函数 赋值(fun)添加window的方法
this 赋值(window)
函数执行上下文
在调用函数,准备执行函数体之前,创建对应的函数执行上下文对象
对局部数据进行预处理
形参变量 赋值(实参) 添加为执行上下文属性
arguments 赋值(实参列表) 添加为执行上下文属性
var 定义的局部变量 undefined 添加为执行上下文属性
function声明的函数 赋值 添加执行上下文的方法
开始执行函数体代码
先执行变量提升在执行函数提升
function a(){
}
var a
console.log(typeof a) 'function'
闭包
如何产生闭包
当一个嵌套的内部函数引用了嵌套的外部函数的变量是,就产生了闭包
闭包到底是什么
内存溢出
一种程序运行出现错误
当程序运行需要的内存超出剩余的内存实时,就抛出内存溢出的错误
内存泄漏
占用的内存没有及时释放
内存泄漏积累多了就容易导致内存溢出
常见的内存泄漏:
意外的局部变量
没有及时清理的计时器或回调函数
闭包
工厂函数
返回一个对象的函数都可以叫工厂函数
原型链继承
子类型原型为父类型实例对象
组合继承
线程和进程
H5中的 Web Workers可以多线程运行
浏览器是多线程,有的是多进程:Chrome,新版IE,有的是进程:
浏览内核
模块:
js引擎
html,css文档解析模块
dom/css模块
布局和渲染相关模块
…
分线程:定时器模块
事件响应模块
网络请求模块
定时器引发的思考
定时器并不能保证定时执行
一般会延迟一丁点,也可能延迟很长事件
定时器回调函数是在分线程执行吗
在主线程执行,js是单线程
定时器是如何实现:
事件循环模型
事件循环模型
执行栈 : 所有代码都是在此空间执行的
浏览器内核:js引擎模块 在主线程处理,其他模块(主/分线程执行)
callback queue :任务队列、 消息队列、事件队列
事件轮询 event loop 一个接一个处理
事件驱动模型
请求响应模型