zoukankan      html  css  js  c++  java
  • js经典题目学习总结

    js经典题目学习总结

    1.foo与getName

    function foo() {
        getName = function () {
            console.log(1);
        }
        return this;
    }
    foo.getName = function () {
        console.log(2);
    }
    foo.prototype.getName = function () {
        console.log(3);
    }
    var getName = function () {
        console.log(4);
    }
    function getName() {
        console.log(5);
    }
    foo.getName();//2
    getName();//4
    foo().getName();//1
    getName();//1
    new foo.getName();//2
    new foo().getName();//3
    new new foo().getName();//3
    
    1. foo.getName();
      直接找到foo.getName然后执行函数输出2
    2. getName()
      由于预解析时函数声明提前于变量声明,所以顺序是这样
      • 声明一个有名函数getName
      • 声明一个变量getName将有名函数getName覆盖,并指向了一个输出4的匿名函数
      • 运行到getName(),输出4
    3. foo().getName()
      执行顺序:
      • 执行foo,由于getName没有用var/let定义,去全局变量找,所以将上一个输出4的getName覆盖,全局getName的输出为1
      • foo执行完返回this,由于没有其他对象调用foo,返回的this就是window
      • 等价于执行window.getName(),输出1
    4. getName()
      由上一步可知此时全局getName输出1
    5. new foo.getName()
      运算符优先级 new foo() > foo() > foo,所以等价于
    vat a=foo.getName;
    new a();//new的时候会将a执行一次,输出2
    
    1. new foo().getName()
      根据优先级,执行步骤等价于
    var a=new foo();//返回foo对象,注意new执行过程中this为a
    a.getName();//去原型链找到getName,输出3
    
    1. new new foo().getName()
      等价代码如下:
    var a=new foo();//foo对象
    var b=a.getName;//foo对象原型链上的getName
    new b();//以b作为构造函数生成新对象,此时会执行一次b输出3
    

    2.输出顺序

    async function async1() {
        console.log('async1 start');
        await async2();
        console.log('async1 end');
    }
    async function async2() {
        console.log('async2');
    }
    
    console.log('script start');
    setTimeout(function () {
        console.log('setTimeout');
    }, 0);
    async1();
    new Promise(function (resolve) {
        console.log('promise1');
        resolve();
    }).then(function () {
        console.log('promise2');
    })
    console.log('script end');
    /*
    结果:
    script start
    async1 start
    async2
    promise1
    script end
    async1 end
    promise2
    setTimeout
    */
    

    题目涉及到异步编程,事件循环,宏任务,微任务等知识点,可以先去另一篇博客了解:事件循环&nextTick原理&异步渲染
    以上代码执行顺序如下:

    1. 执行所有的同步代码,特别注意Promise的then以前的代码async函数第一个条await语句里面的代码立即执行,是属于同步代码的
    script start
    async1 start
    async2
    promise1
    script end
    
    1. 根据代码顺序执行微任务代码(Promise的then函数,await返回的也是Promise对象)
    async1 end
    promise2
    
    1. 执行宏任务回调(SetTimeout,setInmidiate等)
    setTimeout
    

    以上为个人理解,如有错误欢迎指正。

  • 相关阅读:
    关于获取路径
    今天最好的生日礼物就是重新找到目标
    Fedora与Ubuntu安装g++的命令
    CMPXCHG8B 比较并交换 8 字节
    关于 WIN32_LEAN_AND_MEAN
    i386和i686
    Intrinsic function
    VC9: LINK : warning LNK4068: /MACHINE not specified; defaulting to X86
    Linux内核中的Min和Max函数
    linux重定向命令应用及语法
  • 原文地址:https://www.cnblogs.com/aeipyuan/p/12783492.html
Copyright © 2011-2022 走看看