this相关的题
1. 题1
function Test1() {
function foo() {
console.log(this.a);
console.log(a); // 2
}
function doFoo() {
console.log(this.a)
foo();
}
var obj = {
a: 1,
doFoo,
};
var a = 2;
obj.doFoo();
}
Test1()
// 1
// undefined
// 2
2. 题2
箭头函数本身没有this,在箭头函数中访问this取决于词法作用域定义下的上下文中的this
function Test2() {
var obj = {
a: 20,
say: () => {
console.log(this.a);
},
};
obj.say();
var anotherObj = { a: 30 };
obj.say.apply(anotherObj);
}
Test2()
// undefined
// undefined
3. 题3
function Test3() {
function a() {
console.log(this);
}
a.call(null);
}
Test3()
// Window or global
4. 题4
function Test4() {
var obj = {
name: "abin",
func: function () {
console.log(this.name);
},
};
obj.func();
new obj.func();
}
Test4()
// abin
// undefined
5. 题5
function Test5() {
var obj = {
say: function () {
var f1 = () => {
console.log(this);
};
f1();
},
pro: {
getPro: () => {
console.log(this);
},
},
};
var o = obj.say;
o(); // o在全局执行,父级say的this指向全局作用域
obj.say(); // obj.say执行时,say的this指向obj,箭头函数使用父级的this
obj.pro.getPro(); // 对象不构成作用域,箭头函数的this指向了全局作用域
}
Test5()
// Window
// obj
// Window
6. 题6
function Test6() {
var myObject = {
foo: "bar",
func: function () {
var self = this;
console.log(this.foo);
console.log(self.foo);
(function () {
console.log(this.foo);
console.log(self.foo);
})(); // 立即执行函数的this指向window
},
};
myObject.func();
}
Test6()
// bar
// bar
// undefined
// bar
7. 题7
function Test7() {
window.number = 2;
var obj = {
number: 3,
db1: (function () {
console.log(this);
this.number *= 4;
return function () {
console.log(this);
this.number *= 5;
};
})(),
};
var db1 = obj.db1;
db1();
obj.db1();
console.log(obj.number);
console.log(window.number);
}
Test7()
// Window
// Window
// obj
// 15
// 40
8. 题8
function Test8() {
function fn() {
console.log(this.length); // 这里两个参数,所以长度为2
}
var obj = {
length: 5,
method: function (fn) {
fn(); // this指向window
arguments[0](); // this指向arguments
},
};
obj.method(fn, 1);
}
Test8()
// undefined
// 2
9. 题9
function Test9() {
var a = 1;
function printA() {
console.log(this.a);
}
var obj = {
a: 2,
foo: printA,
bar: function () {
printA();
},
};
obj.foo(); // this指向对象
obj.bar(); // printA的this指向了window
var foo = obj.foo;
foo();
}
Test9()
// 2
// undefined
// undefined
10. 题10
var x = 3;
var y = 4;
// 题10
function Test10() {
var obj = {
x: 1,
y: 6,
getX: function () {
var x = 5;
return (function () {
return this.x;
})();
},
getY: function () {
var y = 7;
return this.y;
},
};
console.log(obj.getX()); // this指向了window
console.log(obj.getY());
}
Test10()
// 3
// 6
11. 题11
var a = 10;
function Test11() {
var obj = {
a: 20,
fn: function () {
var a = 30;
console.log(this.a);
},
};
obj.fn();
obj.fn.call(); // call没有指定参数,this指向window
(obj.fn)(); // 括号表示优先级不影响结果
}
Test11();
// 20
// 10
// 20
12. 题12
function Test12() {
function foo(something) {
this.a = something
}
var obj1 = {
foo
}
var obj2 = {}
obj1.foo(2)
console.log(obj1.a); // 2
obj1.foo.call(obj2, 3)
console.log(obj2.a); // 3
var bar = new obj1.foo(4)
console.log(obj1.a); // 2
console.log(bar.a); // 4
var bindFn = obj1.foo.bind(obj2)
bindFn(7)
var bar2 = new bindFn(8)
console.log(obj2.a); // 7
console.log(bar2.a); // 8
}
Test12()
// this绑定的优先级: new绑定 > 显式绑定 > 隐式绑定 > 默认绑定
// 2
// 3
// 2
// 4
// 7
// 8
作用域相关
1. 题1
function Test1() {
(function () {
var x = (y = 1); // 从右往左执行,y=1,y为全局变量, x是局部变量
})();
var z;
console.log(y);
console.log(z);
console.log(x);
}
Test1()
// 1
// undefined
// Uncaught ReferenceError:x is not defined
2. 题2
function Test2() {
var a, b;
(function () {
console.log(a);
console.log(b);
var a = (b = 3);
console.log(a);
console.log(b);
})();
console.log(a);
console.log(b);
}
Test2()
// undefined
// undefined
// 3
// 3
// undefined
// 3
3. 题3
function Test3() {
var friendName = "World";
(function () {
if (typeof friendName === "undefined") {
var friendName = "Jack"; // 此处的var声明,导致变量提升,没有块级作用域
console.log("Goodbye " + friendName);
} else {
console.log("Hello " + friendName);
}
})();
console.log(friendName)
}
Test3();
// Goodbye Jack
// World
4. 题4
function Test4() {
function fn1() {
console.log("fn1");
}
var fn2; // 函数赋给变量,不会发生函数提升
fn1();
fn2();
fn2 = function () {
console.log("fn2");
};
fn2();
}
Test4()
// fn1
// TypeError: fn2 is not a function
5. 题5
function Test5() {
function fn1() {
console.log("fn1");
}
fn1();
fn2();
function fn2() { // 函数变量提升
console.log("fn2");
}
fn2();
}
Test5()
// fn1
// fn2
// fn2
6. 题6
function Test7() {
window.number = 2;
var obj = {
number: 3,
db1: (function () {
console.log(this);
this.number *= 4;
return function () {
console.log(this);
this.number *= 5;
};
})(),
};
var db1 = obj.db1;
db1();
obj.db1();
console.log(obj.number);
console.log(window.number);
}
Test7()
// Window
// Window
// obj
// 15
// 40
7. 题7
function Test8() {
function fun(n, o) {
console.log(o);
return {
fun: function (m) {
return fun(m, n);
},
};
}
var a = fun(0);
a.fun(1);
a.fun(2);
a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(1);
c.fun(2);
c.fun(3);
}
Test8()
// undefined
// 0
// 0
// 0
// undefined
// 0
// 1
// 2
// undefined
// 0
// 1
// 1
8. 题8
g = function () {
return false;
};
f = function () {
return true;
};
function Test9() {
(function () {
if (window.g() && [] == ![]) {
f = function () {
return false;
};
function g() {
return true;
}
}
})();
console.log(f());
}
Test9();
// true
原型链相关
1. 题1
function Test1() {
function Person(name) {
this.name = name
}
var p2 = new Person('king')
console.log(p2.__proto__); // {constructor: Person}
console.log(p2.__proto__.__proto__); // Object.prototype
console.log(p2.__proto__.__proto__.__proto__); // null
console.log(p2.constructor); // Person
console.log(p2.prototype); // undefined
console.log(Person.constructor); // ƒ Function() { [native code] }
console.log(Person.prototype); // {constructor: Person}
console.log(Person.prototype.constructor); // Person
console.log(Person.prototype.__proto__); // Object.prototype
console.log(Person.__proto__); // ƒ Function() { [native code] }
console.log(Function.prototype.__proto__); // Object.prototype
console.log(Function.__proto__); // ƒ Function() { [native code] }
console.log(Function.__proto__.__proto); // Object.prototype
console.log(Object.__proto__); // ƒ Function() { [native code] }
console.log(Object.prototype.__proto__); // null
}
Test1()
2. 题2
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
3. 题3
function Test3() {
var F = function () {
}
Object.prototype.a = function () {
console.log('a');
}
Function.prototype.b = function () {
console.log('b');
}
var f = new F()
f.a() // a
f.b() // Uncaught TypeError: f.b is not a function
F.a() // a
F.b() // b
}
Test3()
4. 题4
function Test4() {
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
}
Test4()
// 4
// 2
// 1
5. 题5
function Test5() {
function Dog() {
this.name = 'puppy'
}
Dog.prototype.bark = () => {
console.log('woof!');
}
const dog = new Dog()
console.log(Dog.prototype.constructor === Dog && dog.constructor === Dog && dog instanceof Dog)
}
Test5()
// true
6. 题6
function Test6() {
var A = { n: 4399 }
var B = function () {
this.n = 9999
}
var C = function () {
var n = 8888
}
B.prototype = A
C.prototype = A
var b = new B()
var c = new C()
A.n++
console.log(b.n); // 9999
console.log(c.n); // 4400
}
Test6()
// 9999
// 4400
7. 题7
function Test7() {
function A() {
}
function B(a) {
this.a = a
}
function C(a) {
if (a) {
this.a = a
}
}
A.prototype.a = 1
B.prototype.a = 1
C.prototype.a = 1
console.log(new A().a); // 1
console.log(new B().a); // undefined
console.log(new C(2).a); // 2
}
Test7()
// 1
// undefined
// 2
8. 题8
function Test8() {
function Parent() {
this.a = 1
this.b = [1, 2, this.a]
this.c = { demo: 5 }
this.show = function () {
console.log(this.a, this.b, this.c.demo);
}
}
function Child() {
this.a = 2
this.change = function () {
this.b.push(this.a)
this.a = this.b.length
this.c.demo = this.a++
console.log('this.c.demo', this.c.demo)
}
}
Child.prototype = new Parent
var parent = new Parent
var child1 = new Child
var child2 = new Child
child1.a = 11
child2.a = 12
parent.show() // 1 [1,2,1] 5
child1.show() // 11 [1,2,1] 5
child2.show() // 12 [1,2,1] 5
child1.change() //this.c.demo 4
child2.change() //this.c.demo 5
parent.show() // 1 [1,2,1] 5
child1.show() // 5 [1,2,1,11,12] 5
child2.show() // 6 [1,2,1,11,12] 5
}
Test8()
// 1 [ 1, 2, 1 ] 5
// 11 [ 1, 2, 1 ] 5
// 12 [ 1, 2, 1 ] 5
// this.c.demo 4
// this.c.demo 5
// 1 [ 1, 2, 1 ] 5
// 5 [ 1, 2, 1, 11, 12 ] 5
// 6 [ 1, 2, 1, 11, 12 ] 5
9. 题9
function Test9() {
function SuperType() {
this.property = true
}
SuperType.prototype.getSuperValue = function () {
return this.property
}
function SubType() {
// this.subproperty = false
this.property = 'aaa'
}
SubType.prototype = new SuperType
SubType.prototype.getSubValue = function () {
return this.subproperty
}
var instance = new SubType
console.log(instance.getSuperValue());
}
Test9()
// aaa
异步相关
题1
// prmise.then是微任务,在所有宏任务执行完之后才会执行, 因为promise一直pending,所以不输出3
function Test1() {
const promise = new Promise((resolve, reject) => {
console.log(1);
console.log(2);
});
promise.then(() => {
console.log(3);
});
console.log(4);
}
Test1()
// 1
// 2
// 4
题2
function Test2() {
const promise1 = new Promise((resolve, rejct) => {
console.log('promise1');
resolve('resolve1');
});
const promise2 = promise1.then((res) => {
console.log(res);
});
console.log('1', promise1);
console.log('2', promise2);
setTimeout(() => {
console.log('1', promise1);
console.log('2', promise2);
}, 0);
}
Test2()
// promise1
// 1 Promise { 'resolve1' }
// 2 Promise { <pending> }
// resolve1
// 1 Promise { 'resolve1' }
// 2 Promise { undefined }
题3
function Test3() {
const promise = new Promise((resolve, reject) => {
console.log(1);
setTimeout(() => {
console.log('timerStart');
resolve('success');
console.log('timerEnd');
}, 0);
console.log(2);
});
promise.then((res) => {
console.log(res);
});
console.log(4);
}
Test3()
// 1
// 2
// 4
// timerStart
// timerEnd
// success
题4
function Test4() {
Promise.resolve().then(() => {
console.log('promise1');
const timer2 = setTimeout(() => {
console.log('timer2');
}, 0);
});
const timer1 = setTimeout(() => {
console.log('timer1');
Promise.resolve().then(() => {
console.log('promise2');
});
}, 0);
console.log('start');
}
Test4()
// start
// promise1
// timer1
// promise2
// timer2
题5
function Test5() {
const promise = new Promise((resolve, reject) => {
resolve('success1');
reject('error');
resolve('success2');
});
promise
.then((res) => {
console.log('then:', res);
})
.catch((err) => {
console.log('catch:', err);
});
}
Test5()
// then: success1
题6
Promise.resolve自动为原始值返回新的Promise对象
then方法接收的参数是函数,如果传入的不是函数,则将其解释为then(null)
function Test6() {
Promise.resolve(1).then(2).then(console.log);
}
Test6();
// 1
题7
在node中
promise1 Promise { <pending> }
promise2 Promise { <pending> }
Error: error!!!
在浏览器中
promise1 Promise { <pending> }
promise2 Promise { <pending> }
Error: error!!!
promise1 Promise {<fulfilled>: 'success'}
Promise2 {<rejected>: Error: error!!! ...}
题8
then的回调会返回一个新的promise,从而实现了链式调用
function Test8() {
Promise.resolve(1)
.then((res) => {
console.log(res);
return 2;
})
.catch((err) => {
return 3;
})
.then((res) => {
console.log(res);
});
}
Test8()
// 1
// 2
题9
function Test9() {
Promise.resolve()
.then(() => {
return new Error('error!!!');
})
.then((res) => {
console.log('then:', res);
})
.catch((err) => {
console.log('catch:', err);
});
}
Test9()
// then: Error: error!!!
题10
function Test10() {
const promise = Promise.resolve().then(() => {
return promise;
});
promise.catch(console.err);
}
// Test10()
// 结果: Uncaught (in promise) TypeError: Chaining cycle detected for promise #<Promise>
// 解析,then或者catch不能返回promise本身,否则会造成死循环
题11
function Test11() {
// 错误被then的第二个参数捕获了,所以就不能被catch了
Promise.reject('err!!!')
.then(
(res) => {
console.log('success', res);
},
(err) => {
console.log('error', err);
}
)
.catch((err) => {
console.log('catch', err);
});
}
Test11()
// error err!!!
题12
finally方法不论Promise最终何种状态都会执行,finally不接受任何参数,它最终返回的是上一个promise的值,如果抛出异常则返回异常的promise对象
function Test12() {
Promise.resolve('1')
.then((res) => {
console.log(res);
})
.finally(() => {
console.log('finally');
});
Promise.resolve('2')
.finally(() => {
console.log('finally2');
return '我是finally2返回的值';
})
.then((res) => {
console.log('finally2后面的then函数', res);
});
}
Test12();
// 1
// finally2
// finally
// finally2后面的then函数 2
题13
function Test13() {
function runAsync(x) {
const p = new Promise((r) =>
setTimeout(() => {
r(x, console.log(x));
}, 1000)
);
return p;
}
Promise.all([runAsync(1), runAsync(2), runAsync(3)]).then((res) => console.log(res));
}
Test13();
// 1
// 2
// 3
// [ 1, 2, 3 ]
题14
如果一组异步操作中有一个异常都不会进入.then的第一个回调函数,会被第二个回调捕获
function Test14() {
function runAsync(x) {
const p = new Promise((r) =>
setTimeout(() => {
r(x, console.log(x));
}, 1000)
);
return p;
}
function runReject(x) {
const p = new Promise((res, rej) =>
setTimeout(() => {
rej(`Error:${x}`, console.log(x));
}, 1000 * x)
);
return p;
}
Promise.all([runAsync(1), runReject(4), runAsync(3), runReject(2)])
.then((res) => console.log(res))
.catch((err) => console.log(err));
}
Test14();
// 1
// 3
// 2
// Error:2
// 4
题15
then只会捕获第一个成功的方法,其他的函数虽然继续执行,但是不被then捕获了
function Test15() {
function runAsync(x) {
const p = new Promise((r) =>
setTimeout(() => {
r(x, console.log(x));
}, 1000)
);
return p;
}
Promise.race([runAsync(1), runAsync(2), runAsync(3)])
.then((res) => console.log('result:', res))
.catch((err) => console.log(err));
}
Test15();
// 1
// result: 1
// 2
// 3
题16
Promise完成后,后续抛出的错误将不会再捕获
function Test16() {
function runAsync(x) {
const p = new Promise((r) =>
setTimeout(() => {
r(x, console.log(x));
}, 1000)
);
return p;
}
function runReject(x) {
const p = new Promise((res, rej) =>
setTimeout(() => {
rej(`Error:${x}`, console.log(x));
}, 1000 * x)
);
return p;
}
Promise.race([runAsync(0), runReject(1), runAsync(2), runReject(3)])
.then((res) => console.log(res))
.catch((err) => console.log(err));
}
Test16()
// 0
// 0
// 1
// 2
// 3
题17
await后的语句相当于放在Promise.then中
function Test17() {
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
async1();
console.log('start');
}
Test17()
// async1 start
// async2
// start
// async1 end
题18
function Test18() {
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
setTimeout(() => {
console.log('timer1');
}, 0);
}
async function async2() {
setTimeout(() => {
console.log('timer2');
}, 0);
console.log('async2');
}
async1();
setTimeout(() => {
console.log('timer3');
}, 0);
console.log('start');
}
Test18()
// async1 start
// async2
// start
// async1 end
// timer2
// timer3
// timer1
题19
Promise一直pending所以await后面的内容不会执行,包括async1的then中
function Test19() {
async function async1() {
console.log('async1 start');
await new Promise((resolve) => {
console.log('promise1');
});
console.log('async1 success');
return 'async1 end';
}
console.log('script start');
async1().then((res) => console.log(res));
console.log('script end');
}
Test19()
// script start
// async1 start
// promise1
// script end
题20
function Test20() {
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(function() {
console.log('promise2');
});
console.log('script end');
}
Test20()
// script start
// async1 start
// async2
// promise1
// script end
// async1 end
// promise2
// setTimeout
题21
async函数抛出错误,不会继续往下执行,可以用catch捕获错误
function Test21() {
async function async1() {
await async2();
console.log('async1');
return 'async1 success';
}
async function async2() {
return new Promise((resolve, reject) => {
console.log('async2');
reject('error');
});
}
async1().then((res) => console.log(res));
}
Test21()
// async2
// Uncaught (in promise) error
题22
Promise一直pending所以await后面的内容不会执行,包括async1的then中
function Test22() {
async function async1() {
console.log('async1 start');
await new Promise((resolve) => {
console.log('promise1');
});
console.log('async1 success');
return 'async1 end';
}
console.log('script start');
async1().then((res) => console.log(res));
console.log('script end');
}
Test22()
// script start
// async1 start
// promise1
// script end
题23
async函数抛出错误,不会继续往下执行,可以用catch捕获错误
function Test23() {
async function async1() {
await async2().catch((e) => console.log(e));
console.log('async1');
return 'async1 success';
}
async function async2() {
return new Promise((resolve, reject) => {
console.log('async2');
reject('error');
});
}
async1().then((res) => console.log(res));
}
Test23()
// async2
// error
// async1
// async1 success
题24
Promise中 resolve之后的代码也会执行的
function Test24() {
const first = () =>
new Promise((resolve, reject) => {
console.log(3);
let p = new Promise((resolve, reject) => {
console.log(7);
setTimeout(() => {
console.log(5);
resolve(6);
console.log(p);
}, 0);
resolve(1);
});
resolve(2);
p.then((arg) => {
console.log(arg);
});
});
first().then((arg) => {
console.log(arg);
});
console.log(4);
}
Test24()
// 3
// 7
// 4
// 1
// 2
// 5
// Promise {1}
题25
function Test25() {
const async1 = async () => {
console.log('async1');
setTimeout(() => {
console.log('timer1');
}, 2000);
await new Promise((resolve) => {
console.log('promise1');
});
console.log('async1 end');
return 'async1 success';
};
console.log('script start');
async1().then((res) => console.log(res));
console.log('script end');
Promise.resolve(1).then(2).then(Promise.resolve(3)).catch(4).then((res) => console.log(res));
setTimeout(() => {
console.log('timer2');
}, 1000);
}
Test25();
// script start
// async1
// promise1
// script end
// 1
// timer2
// timer1
题26
function Test26() {
const p1 = new Promise((resolve) => {
setTimeout(() => {
resolve('resolve3');
console.log('timer1');
}, 0);
resolve('resolve1');
resolve('resolve2');
})
.then((res) => {
console.log(res);
setTimeout(() => {
// 如果这个then不返回值,那么p1的Promise值最终为undefined
console.log(p1);
}, 1000);
// return res
})
.finally((res) => {
console.log('finally', res);
});
}
Test26()
// resolve1
// finally undefined
// timer1
// Promise <fulfilled undefined>
题27
function Test27() {
console.log(1);
setTimeout(() => {
console.log(2);
process.nextTick(function () {
console.log(3);
});
new Promise(function (resolve) {
console.log(4);
resolve();
}).then(function () {
console.log(5);
});
});
process.nextTick(function () {
console.log(6);
});
new Promise(function (resolve) {
console.log(7);
resolve();
}).then(function () {
console.log(8);
});
setTimeout(() => {
console.log(9);
process.nextTick(function () {
console.log(10);
});
new Promise(function (resolve) {
console.log(11);
resolve();
}).then(function () {
console.log(12);
});
});
}
Test27();
// 1
// 7
// 6
// 8
// 2
// 4
// 3
// 5
// 9
// 11
// 10
// 12
题28
function Test28() {
console.log(1);
setTimeout(() => {
console.log(2);
});
new Promise((resolve) => {
console.log(3);
resolve(4);
}).then((d) => console.log(d));
setTimeout(() => {
console.log(5);
new Promise((resolve) => {
resolve(6);
}).then((d) => console.log(d));
});
setTimeout(() => {
console.log(7);
});
console.log(8);
}
Test28();
// 1
// 3
// 8
// 4
// 2
// 5
// 6
// 7
题29
function Test29() {
console.log(1);
setTimeout(() => {
console.log(2);
Promise.resolve().then(() => {
console.log(3);
});
});
new Promise((resolve, reject) => {
console.log(4);
resolve(5);
}).then((data) => {
console.log(data);
});
setTimeout(() => {
console.log(6);
});
console.log(7);
}
Test29();
// 1
// 4
// 7
// 5
// 2
// 3
// 6
题30
function Test30() {
Promise.resolve()
.then(() => {
console.log(1);
throw 'Error';
})
.then(() => {
console.log(2);
})
.catch(() => {
console.log(3);
throw 'Error';
})
.then(() => {
console.log(4);
})
.catch(() => {
console.log(5);
})
.then(() => {
console.log(6);
});
}
Test30();
// 1
// 3
// 5
// 6
题31
function Test31() {
setTimeout(() => {
console.log(1);
}, 100);
new Promise(function (resolve) {
console.log(2);
resolve()
console.log(3);
}).then(function () {
console.log(4);
new Promise((resolve, reject) => {
console.log(5);
setTimeout(() => {
console.log(6);
}, 10);
})
})
console.log(7);
console.log(8);
}
Test31()
// 2
// 3
// 7
// 8
// 4
// 5
// 6
// 1