js部分高级内容

守給你的承諾、 提交于 2020-03-27 06:06:01

数据类型

基本: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)初始化代码执行完,再从回调队列中执行

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!