zoukankan      html  css  js  c++  java
  • JS 基础知识复习

    作为一名前端工程师,js的重要性毋庸置疑,但是js的教程呢,感觉是群魔乱舞,要么是后端大佬的解读,要么是半桶水的解读,让人十分困惑,当然,可能就是自己菜而已,理解的不深入,提到this总是让人瑟瑟发抖,各种this的面试题总有让你直呼不懂的地方,不过呢,最近看到了B站上一个视频教程,讲的比较清楚,对于堆栈,函数执行,this指向等问题做了比较详细的解答,今天算是自己的复习理解,如果发现有哪些地方自己不清楚的,在回去看一遍,加深理解。

    那就一个一个的来吧,

    如何查找上级作用域????其实很简单,就一句话

    这个函数在哪个作用域下定义的,那么它的上级作用域就是谁,和函数在哪儿执行没半毛线关系
    文字描述比较苍白,看下面的一个例子吧

        <script>
            var num = 12;
            function fn() {
                var num = 120;
                return function () {
                    console.log(num); 
                }
            }
            var f = fn();
            f()
            ~function () {
                var num = 1200;
                f()
            }()
        </script>
    
    //结果都是120,因为返回的函数是定义在fn里面,而fn里面的num=120,所以结果都是120
    

    关于内存释放和作用域销毁!!

    • 堆内存 一般手动销毁就是设置为null
    • 栈内存,这里的情况就稍微复杂一点
      1. 如果不小心形成了闭包,那么是不会销毁的
      2. 在一个私有作用域中,给DOM元素绑定事件,一般情况下,这个私有作用域是不会被销毁的,可以参考下面的例子2

    例子1

    function fn(){
    var num=10;
    return function(){
    }
    }
    
    var f=fn()
    

    例子2

    <div id="div1">点我啊</div>
    //script
    
    ~function(){
         var odiv=document.getElementById('#div1');
          odiv.onclick=function(){
          xxxx
    }
    
    }()
    
    
    

    其实这个不销毁的原理和上面的是一样的,因为dom元素也是一个对象,默认情况下,dom元素对象里面的onclick属性=null,但是我们给他赋值为一个方法之后,导致这个方法被本作用域外不引用了,请看下图

    js数据类型分为基本数据类型和复杂数据类型,复杂数据类型基本就是指对象了(包括,对象,数组,函数)
    基本数据类型都存储在内存的栈中
    复杂数据存储在堆中

    JS在执行的过程中,会先预解释,也就是变量提升,然后在从上往下执行,碰到复杂类型数据,就在放在堆中,并且将地址赋值给栈中的变量
    这里需要提一下,函数在定义的时候,堆里面只是存的是函数体里面的字符串,等到函数执行的时候,会将代码放到栈里面来执行

    函数在执行的时候,会在栈里面开辟出一个空间,作为函数的私有作用域,然后里面也会有一系列的流程
    1,形参赋值
    2,预解释
    3,从上往下执行
    执行完之后,一般会将这个栈空间销毁,也叫出栈。
    这里又会引出一个概念,闭包,这个空间就不会被销毁
    要形成闭包呢,需要在一个私有作用域中,也就是一个大函数中,返回一个引用类型的数据,最关键的地方是,这个返回的数据要被赋值给外面的一个变量,这样子,在这个作用域之外的地方也有变量引用了这个数据,此时就形成了闭包。
    之前呢,我一直以为函数里面返回了函数,就形成了闭包,事实上不是,还需要非常关键的被外界引用

    然后就是this指向了。
    this指向的是当前行为的执行主体,JS里面还有context(上下文)的概念,就是这个主体所处在的环境(区域),
    例如:张三 在 沙县 吃云吞 =》this就是张三,context就是沙县小吃,行为就是吃云吞,this和context没有啥必然联系,张三可以在沙县吃,也可以在上海小混沌吃,对吧
    this的指向与方法在哪儿定义和在哪儿执行没有啥关系,那么如何判断this指向呢,很简单,下面的规律
    1,如果某个函数前面有“.”,那么这个“.”前面是谁,this就是谁,如果没有“.”,那this就指向window
    2,自执行函数里面的this永远指向window
    3,给元素中的某一个事件绑定方法,当事件触发的时候,执行对应的方法,方法中的this就指向当前元素

    `html

    点我啊

    function fn(){
    console.log(this);
    }
    var obj={fn:fn};
    fn(); //this=>window
    obj.fn() // this=>obj
    function sun(){
    console.log(this) //window
    fn() // this=>window
    }
    sun();
    var oo={
    sum:function(){
    console.log(this) // oo
    fn(); //this=>window
    }
    }
    oo.sum()

    document.getElementById("#div1").onclick=fn //此时fn里面的this指向#div1

    document.getElementById("#div1").onclick=function(){
    console.log(this); // this指向#div1
    fn() // this指向window

    }
    //上面是规律,下面看看一道面试题
    var num = 20;
    var obj = {
    num: 30,
    fn: (function (num) {
    this.num *= 3;
    num += 15;
    var num = 45;
    return function () {
    this.num *= 4;
    num += 20;
    console.log(num);
    }
    })(num)
    };
    var fn = obj.fn;
    fn(); //65
    obj.fn();//85
    console.log(window.num, obj.num); //240 120

    
    

    这是例子
    var obj={
    name:'张三',
    say:function(){
    console.log(window)
    console.log(this.name)
    }
    }

    obj.say(); //张三
    var o1=obj.say
    o1();// this指向window

    在来一个例子
    

    function Fn(name) {
    this.name = name;
    this.say = function () {
    console.log('hello' + this.name + 'hahahaah');
    }
    }

    var f1=new Fn("张三");
    f1.say() //say 函数里面的this 指向需要say执行的时候来确定 此时say前面的“.”前面是f1,那么这this指向的就是f1
    // 构造函数里面的this.name的this就是指向具体的实例,这里就是指向f1,虽然结果一样,但是两个的原理不一样

    
    这是一个系列,不过放一片文章里面还是太长了,后续还是分出不同的标题吧
    
    写篇文章真是不容易呀,那些大佬写的那么些高质量的文章 真不知道肝了多少精力和脑细胞。
  • 相关阅读:
    c语言printf实现同一位置打印输出
    https加解密过程
    矩形重叠判断
    cocos creator Touch事件应用(触控选择多个子节点)
    js动态创建类对象
    HTTP ERROR 400 Bad Request
    JavaScript(JS)计算某年某月的天数(月末)
    spring hibernate实现动态替换表名(分表)
    Zookeeper实现分布式锁
    Spring FactoryBean和BeanFactory 区别
  • 原文地址:https://www.cnblogs.com/ysla/p/14130903.html
Copyright © 2011-2022 走看看