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

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

posted @ 2020-04-21 11:37  aeipyuan  阅读(232)  评论(0编辑  收藏  举报