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

以上爲個人理解,如有錯誤歡迎指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章