题目一:
{
function test() {
let n = 4399;
function add() {
n++;
console.log(n);
}
return {n:n,add:add};
};
let re = test();
let re2 = test();
re.add();// 4400
re.add();// 4401
console.log(re.n);//4399
re2.add()//4400
}
输出结果:4400 4401 4399 4400。
第一步:let re = test();这一句就已经把test函数执行了一遍,然后re保存的就是:{n:4399,add:function add(){}}。
第二步:let re2 = test(),这一句会重新执行一次test函数,re2保存的就是一个新的{n:4399,add:function add(){}}。
第三步:re.add(),就是直接调用函数中的add函数(这里形成了闭包,test中的n变量就不会被垃圾回收机制回收掉),对n进行加1,然后输出4400。
当再次调用re.add(),这时候的n还是同一个n,n在第一次调用的时候就变成了4400,然后再次调用,变成4401,然后打印re.n,这时候的n在let re = test()的时候就已经保存了,且后面调用add并没有对这个n进行修改。
第四步:最后re2.add(),就相当于第一次运行re.add。所以输出4400
题目二:
{
function F(){}
Object.prototype.a = function () { };
Function.prototype.b = function () { };
let f = new F();
console.log(f.a);//[Function (anonymous)]
console.log(f.b);//undefined
}
首先先去了解原型链的继承关系,每个实例都有__ proto__属性,所以构造函数都有prototype属性,且每个实例的__ proto__属性和创建它的构造函数的prototype属性指向同一个对象。
f.a会从自身寻找到原型链的最顶端(null)。
F相当于是Function的实例,F是Function的实例,那么F.__ proto__ ==Function.prototype,但是f是构造函数F的实例,所以f.__ proto__属性 == F.prototype,F.__ proto__属性才等于Function.prototype,所以Function.prototype属性并没有在f的原型链上。
f.__ proto __ .__ proto __ == Object.prototype//返回true,所以a是在f的原型链上,但是Function不在。
题目三:
{
let myObject = {
foo: "bar",
func: function () {
let self = this;
console.log(this.foo);
console.log(self.foo);
(function () {
console.log(this.foo);
console.log(self.foo);
})()
}
}
myObject.func();
}
输出结果:bar bar undefined bar
首先func函数中的this的指向就是谁调用它就指向谁。
myObject.func(),myObject就是调用func的上下文,然后把this赋值给了self,所以前两句都能访问到foo属性,但是立即执行函数中的this是指向全局的,self还是继承外层的self,所以输出 bar bar undefined bar。
题目四:
{
function foo() {
let i = 0;
return function () {
console.log(i++);
}
}
let f1 = foo();
let f2 = foo();
f1();
f1();
f2();
}
输出结果:0 1 0
let f1 = foo(); 这一句执行过后,f1就保存返回的函数,然后f1()就是执行一次该函数,对n进行打印,log(i++),首先先打印i,再对i进行++,当第二次调用f1()之前,i已经是1了,然后再执行该函数,打印1,再加一。
然后f2就相当于又是一个新的foo函数执行得到的函数,f1不等于f2。
所以f2(),就输出0.
题目五:
{
(function () {
var x = foo();
var foo = function foo() {
return "foo"
}
return x;
})()//类型错误,foo不是一个函数。
}
函数声明会被提升,但是函数表达式却不会被提升。
首先会进行var关键字声明的变量,会进行变量提升,var x = foo(),这里的foo在下面用var关键字进行了声明,所以会进行变量提升,foo就是undefined,所以undefined()就直接报错。
题目六:
{
var name = "World";
(function () {
var name;
if (typeof name == 'undefined') {
name = "Jack";
console.log("Goodbye "+name);
} else {
console.log("Hello "+name);
}
})()
}
输出结果:Goodbye Jack
在函数作用域中,首先会在内部寻找变量是否存在,不存在然后再去外层寻找,所以这里的name声明了还没定义,所以就是undefined。