1、下面函数执行结果
const o = {
a: 10,
fn: function (){ return this.a*2;},
fn1: ()=> this.a * 2,
obj: {
a: 20,
fn: function (){ return this.a*2;},
fn1: () => this.a * 2,
}
}
o.fn(); // 结果: 20
o.fn1(); // 结果: NaN
o.obj.fn(); // 结果: 40
o.obj.fn1(); // 结果: NaN
2、下面函数执行结果
function a() {
console.log(a);
var a = 5;
console.log(b);
console.log(a);
let b = 6;
}
a(); // 结果: Cannot access 'b' before initialization
3、下面函数执行结果
function Foo(){
Foo.a=function(){
console.log(1) ;
},
this.a=function(){
console.log(2) ;
}
}
Foo.prototype.a=function() {
console.log(3) ;
}
Foo.a = function(){
console.log(4) ;
}
Foo.a() ; // 结果:4
let obj=new Foo() ;
obj.a() ; // 结果:2
Foo.a() ; //结果:1
// 答案:4 2 1
解析:
- Foo.a() 这个是调用 Foo 函数的静态方法 a,虽然 Foo 中有优先级更高的属性方法 a,但 Foo此时没有被调用,所以此时输出
Foo 的静态方法 a 的结果:4 - let obj = new Foo(); 使用了 new方法调用了函数,返回了函数实例对象,此时 Foo
函数内部的属性方法初始化,原型链建立。obj.a() ; 调用 obj实例上的方法 a,该实例上目前有两个 a
方法:一个是内部属性方法,另一个是原型上的方法。当这两者都存在时,首先查找ownProperty,如果没有才去原型链上找,所以调用实例上的 a 输出:2 - Foo.a() ; 根据第2步可知 Foo函数内部的属性方法已初始化,覆盖了同名的静态方法,所以输出:1
4、下面函数执行结果
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(()=>{
console.log('setTimeout');
},0);
async1();
new Promise((resolve)=>{
console.log('promise1');
resolve();
}).then(()=>{
console.log('promise2');
});
console.log('script end');
答案:
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
注意以下几点:
- Promise 优先于 setTimeout 宏任务,所以 setTimeout 回调会最后执行
- Promise 一旦被定义就会立即执行
- Promise 的 resolve 和 reject 是异步执行的回调。所以 resolve() 会被放到回调队列中,在主函数执行完和
setTimeout 之前调用 - await 执行完后,会让出线程。async 标记的函数会返回一个 Promise 对象
解析:
- 首先,事件循环从宏任务(macrostack)队列开始,这个时候,宏任务队列中,只有一个 script
(整体代码)任务。从宏任务队列中取出一个任务来执行。 - 首先执行 console.log(‘script start’),输出 ‘script start’
- 遇到 setTimeout 把 console.log(‘setTimeout’) 放到 macrotask 队列中
- 执行 aync1() 输出 ‘async1 start’ 和 ‘async2’ ,
- 把 console.log(‘async1 end’) 放到 micro 队列中 执行到 promise ,输出 ‘promise1’ ,
- 把 console.log(‘promise2’) 放到 micro 队列中 执行 console.log(‘script
end’),输出 ‘script end’ - macrotask 执行完成会执行 microtask ,把 microtask quene 里面的 microtask全部拿出来一次性执行完,所以会输出 ‘async1 end’ 和 ‘promise2’ 开始新一轮的事件循环,去除执行一个
macrotask 执行,所以会输出 ‘setTimeout’