数据类型
基本: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