数据类型
基本:String,Number,boolean(true,false),undefined(undefined),null(null) 引用类型:Object,Function(可以执行),Array(数值下标,有序) 特别地,null无值的对象(用来清空对象),NaN无值的数字,undefined不存在或者存在未赋值 typeof 返回数据类型的字符串形式(小写) 判断字符串,数值,布尔,函数可行。未定义和undefined都返回undefined也勉强可,null和其他引用类型返回object不可(null和undefined用===) instanceof判断实例对象与类(沿原型链向上找)的关系,返回布尔值
var声明局部变量(不可删),直接赋值沿原型链向上找成window的一个属性(可删)
沿作用域链找不到没定义报错,沿原型链找不到是undefined
只有通过属性改变的引用对象才使相同的改变
obj.age=15//有效
obj={age:15}//无效,更改了引用地址
function fn(obj){console.log(obj)}//函数传入的obj是传入参数的一个引用值,与原变量无关(重要),一种基本值,一种引用值(地址)
自动释放和垃圾回收器回收
function fn(){var b={name:'alice'}}
//未被引用的才会被释放回收
//函数执行完,局部变量b立即销毁自动释放,在栈中,系统自动
//{name:'alice'}等待垃圾回收器回收,堆中,等待垃圾回收
call和apply与bind
//更改函数的this,使函数成为(被)任意对象的方法调用
function fn(i){console.log(i+this.age)}
fn.call(window,'年龄是:')//第一个传入谁的this,第二个之后是函数参数,相当于window.fn('年龄是')
//apply与call用法一样,但是第二个参数之后用数组表示
fn.apply(window,['年龄是:'])
//call和apply修改后会立刻调用函数而bind返回不调用
常用bind(this)
基本回调函数
//dom事件回调函数 //定时器回调函数 //ajax回调函数 //生命周期回调函数
IIFE
//立即执行函数表达式 1.隐藏实现,向外暴露 2.不污染,立即销毁 3.编写js模块
句尾不写分号的规则
必须加分号(建议段首) //小括号开头的 //中括号开头的 //+ - /
原型
//1.每个函数都有一个prototype属性(显式原型),默认指向Object对象实例(原型对象)
fun.prototype
//原型对象实例有一个constructor属性,指向函数对象
fun.prototype.constructor===fun
//2.每个实例对象都有一个__proto__属性(隐式原型)本身找不到去__proto__下找
function Fn(){
//默认执行this.prototype = {}
}
console.log(Fn.prototype)
var fn = new Fn()//默认执行this.__proto__ = Fn.prototype
console.log(fn.__proto__)
3.给显示原型添加方法供调用,不能给隐式添加(es6之前)
4.fn.prototype.__proto__是初始的实例对象
fn.prototype.__proto__.__proto__是null
5.所有函数对象是函数的实例对象,即有__proto__为Function.prototype
6.Function()本身调用自身生成,它的__proto__与prototype相等
var Foo = new Function()
Function = new Function()
7.Function.prototype.__proto__.__proto__是null
8.设置对象的属性是在当前对象的链上设置,不去设置修改原型

变量提升(后)和函数提升(先)(存在分歧,结果一致)
//var 定义的变量会提升至开头,值为underfined
//function 定义的函数会提升至开头,值为函数体(存在争议(结果一样):函数先提升,变量后提升,定义变量不会覆盖函数,赋值变量会覆盖函数)
// if里面的也会先提升
var a=5
function fn(){
console.log(a)//undefined
var a=6
}
var fn = function (){}//fn为undefined
执行上下文
//全局执行上下文:
1.确定window为全局执行上下文
2.进行数据预处理:1)var添加为window属性undefined
2)function添加window方法
3)this赋值window
3.执行全局代码
//函数执行上下文 1.确定函数执行上下文(栈中虚拟的) 2.数据预处理: 1)形参赋值,填为属性 2)arguments形参伪数组(实为对象)赋值,填为属性,arguments.callee为原函数 3)var 4)function 5)this 3.执行函数体代码
作用域与作用域链
//变量从当前开始找,没找到沿作用域链向上找
//作用域(静态)与函数执行上下文(动态)个数:作用域是定义函数的n加一,执行上下文是调用函数的n加一
//important 作用域链定义即确定,函数被调用时与调用的无关
//所以一切就是在函数定义时就决定好了
var x=10
function fn(){
console.log(x)
}
function show(f){
var x=20
f()
}
show(fn)//打印x为10
伪数组
//argumnets 和节点数组等,不具有pop(),push()等方法 //特别:伪数组的长度属性不存在,所以每次都要重新计算,最好先赋值取出再使用
闭包
//闭包:内部嵌套函数引用了外部嵌套函数变量或函数
//闭包是:1)内部嵌套函数(不不不) 2)内部函数包含的内部引用的变量组成的对象
//何时产生:执行了外部函数(内部函数定义时)
常用来:
1)将内部函数作为返回值
//返回的内部函数一般用来对变量进行指定的操作
function fn1(){
var a = 2
function fn2(){
a++
console.log(a)
}
return fn2
}
2)将函数作为实参传入另个函数
//闭包作用:1)函数内部变量在函数执行后仍保存 2)使外部可以变相访问内部的变量(外部指向不消失)
//外部函数变量—>被内部函数引用—>被外部指向引用—>外部间接操作内部变量
//闭包应用:自定义模块(将数据和函数封装)
1) function myModule(){
var test = 'this is a test'
function fn1(){
console.log(test.toUpperCase())
}
function fn2(){
console.log(test.toLowerCase())
}
return {fn1:fn1,fn2:fn2}
}
2)( function myModule(window){
var test = 'this is a test'
function fn1(){
console.log(test.toUpperCase())
}
function fn2(){
console.log(test.toLowerCase())
}
window.myModule = {fn1:fn1,fn2:fn2}//常用
})(window)
闭包缺点:变量用后忘记释放(fn=null解决)
内存溢出和泄露
//内存溢出:内存不足,剩余的不够了。 //内存泄露:占用的内存未及时释放。(意外的全局变量,定时器,闭包等)
题
var name = 'name'
var obj = {
var name = 'objName'
getName:function (){
return function (){
return this.name
}
}
}
console.log(obj.getName()())//name
var name = 'name'
var obj = {
var name = 'objName'
getName:function (){
var that = this
return function (){
return that.name
}
}
}
console.log(obj.getName()())//objName
function fun(n,o){
console.log(o)
return {
fun:function(m){
return fun(m,n)
}
}
}
var a = fun(0); a.fun(1);a.fun(2);a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(1); c.fun(2); c.fun(3);
变量找作用域链,变量的属性和函数去找原型链
继承
原型链继承
子构造函数的对象原型等于父构造函数的实例
var 子.prototype = new 父() //父函数如果需要传参数的难搞
子.prototype.constructor = 子
构造函数继承(假)
在子构造函数里先调用 父.call(this,参数们)
组合继承(真正)
function Father( name, age){
this.name = name
this.age = age
}
Father.prototype.setAge=function (num){
this.age+=num
}
function Son( name, age, hobby){
Person.call(this,name,age)//可以得到父亲的属性
this.hobby = hobby
}
Son.prototype = new Person()//可以得到父亲的函数
Son.prototype.constructor = Son
事件循环模型
//先执行初始化代码(同步),再执行回调代码(异步) //事件循环模型 //js 引擎 是单线程的 //js引擎(堆栈)配合WebAPIs和回调队列(任务,消息,事件队列) //程序是在栈里执行
H5 webworks多线程
//主程
var worker = new Worker('worker.js的路径')
work.postMessage(postData)
work.onmessage = function (event){console.log(event.data)}
//worker.js
//分线程全局对象不是window,不能调用dom和相关的
var onmessage = function (event){
console.log(event.data)//接收的数据
postMessage(postData)//返回的数据
}
浏览器内核模块
主线程: js引擎模块:js代码的编译与运行 html,css文档解析模块:解析页面的文本 dom,css模块:在内存中文本转化对象处理等 布局和渲染:根据内存的对象进行页面布局绘制 分线程: 定时器 dom事件 ajax请求 运行流程 1)执行初始化代码,将各种回调函数交给对应的模块处理 2)当事件发生或处理完成,会将回调函数的结果返回到回调队列 3)初始化代码执行完,再从回调队列中执行
来源:https://www.cnblogs.com/liqunblog/p/8277778.html