JavaScript函数对象面试题解析

1.看下面代码将会输出什么?
var foo = 1;
(function (){
console.log(foo);//undefined
var foo = 2;
console.log(foo);//2
})();
函数的声明与变量声明会被js引擎隐式地提升到当前作用域的顶部,但是只提升名称赋值留在原地
2. 完成整个原型链(Student.proto、Student.prototype.__proto__等又是指向谁,原型链的顶端到底是什么,在图中做出体现
function Student(sname, sage){
this.sname = sname;
this.sage = sage;
}
Student.prototype.intr = function(){
console.log(I'm ${this.sname},I'm ${this.sage});
}
var lilie = new Student(“Li Lei”, 12);
var hmm = new Student(“Han Meimei”, 12);
console.log(lilie,hmm);
在这里插入图片描述

	**3.下面代码 将会输出的结果?(并解析)**
	function f1(){
		var n =999;
		nAdd = function(){n+=1}
		function f2(){
			alert(n);
		}
		(function (n){
		alert("remove:"+n);
	})(n);
	return f2;
	}
	var result = f1();
	result();
	nAdd();
	f1();
	result();
	在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是999,第二次的值是1000。

这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。
为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,
因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。
这段代码中另一个值得注意的地方,就是"nAdd=function(){n+=1}"这一行,首先在nAdd前面没有使用var关键字,
因此nAdd是一个全局变量,而不是局部变量。其次,nAdd的值是一个匿名函数(anonymous function),
而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。
4.求输出的结果
var i = 10;
function b(){
i = 20;
console.log(i);//20
for(var i = 0;i < 6;i++){
console.log(i);//输出0-5
}
console.log(this.i);//10
console.log(i);//6 当前的局部变量在循环时被赋值为6

        } 
        b();//等于window.b() 函数里面的this纸袋window对象
        console.log(i)//10  不能向下搜索作用域而进入另一环境

5.解析下面代码并求出结果
function aaa(){
a=10;
}
aaa();
alert(a); //结果为10;
//等价于:
var a;
function aaa(){
a=10;
};
aaa();
alert(a);

给未声明的变量赋值,此变量就会变成全局变量;var a=b=10; 可以解析成 b=10;var a=b; 也就是b为全局变量,a为局部变量,所以外部访问a访问不到,访问b结果为10;
所以为了避免出现这种隐患,我们在定义变量的时候把所有要定义的变量都加上var;

6.alert(a)结果为什么是undefined?
function aaa(){
var a=b=10;
}
aaa();
alert(a);//结果为,无法访问到
alert(b);//结果为10;

变量的查找是就近原则去寻找,定义的var变量;第二点,变量的声明被提前到作用域顶部,赋值保留在原地,
7.求各部分的输出结果并解释
function aaa(){
alert(a);
var a=20;
}
aaa(); //结果为:undefined

				var a=10;
				function aaa(){
				  alert(a);
				  var a=20;
				}
				aaa(); //结果为:undefined
				可以解析为是:
				var a=10;
				function aaa(){
				  var a; //声明提前了
				  alert(a);
				  a=20; //赋值扔留着原地
				}
				aaa();

8. result=? 并解析
function test(){
var n=4399;
function add(){
n++;
console.log(n);//4400
}
return {
n:n,
add:add
}
}
var result=test(); //设置result的属性为:{n:4399,add:add()}
var result2=test(); //设置result2的属性为:{n:4399,add:add()}

					result.add();                //调用result的add方法,执行n++,所以n=4399+1=4400,输出4400

					result.add();                //再次调用result的add方法,此时n=4400,所以执行n++后,所以n=4401
					console.log(result.n);  //这是输出result属性n的值,所以输出4399
					result2.add();              //调用result2的add方法,此时n=4399,所以执行n++后,所以n=4400

9.解释下面代码的输出结果
var color=‘green’;
var test4399={
color:‘blue’,
getColor:function(){
var color=‘red’;
alert(this.color);
}
}
var getColor=test4399.getColor;
getColor();

					test4399.getColor();

					输出 green blue

					解析:
					考察点一:js函数调用时加括号和不加括号的区别,加括号是把函数返回值赋给等号左边,而不加括号相当于把函数代码赋给等号左边。所以代码var getColor=test4399.getColor;相当于var getColor=function(){var color='red';alert(this.color);}

					考察点二:js中this的用法,this总是指向调用它的对象。所以getColor();执行时,相当于Windows调用的,this指向Windows,所以找到的是全局变量中的color,为green。同理,test4399.getColor()是test4399调用的,this指向test4399,所以找的是test4399里的color,为blue。

10.求下面代码输出结果
function Foo(){

					var i=0;
					return function(){
					document.write(i++);
					}
					}
					var f1=Foo();
					f2=Foo();
					f1();//0
					f1();//1
					f2();//0

输出的结果是 0 1 0

解析:这是一个闭包,闭包的作用有两个,一是可以读取函数内部的变量,二是让这些变量的值始终保存在内存中。当f1()和f2()调用时,会创建两个执行环境,保存各自的变量对象,之间是没有相互影响的。而同一个函数多次调用时返回值会被保存到同一个变量对象中,因为闭包i会保存在内存中没有被释放。另外i++是先调用再+1,++i是先+1再调用,所以输出为 0 1 0。

 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

输出为 9999 4400

理解:由题目可知,B和C的原型都指向A;b c 分别是B C的实例;然后A的n进行了一次自增,再分别调用两个实例对象看看输出n的值是多少。

解析:首先我们要知道new运算的具体执行过程:
(1)创建一个空对象
(2)把这个空对象的_proto_指向构造函数的prototype
(3)把这个空对象赋值给this
(4)执行构造函数内的代码
所以当执行var b=new B()时,此时的this指向了新对象,this.n=9999等价于b.n=9999,然后访问b.n,在查找b.n时首先是查找b对象自身有没有n属性,如果没有再去原型(prototype)上找,这里存在,所以返回9999;

   同理,执行var c=new C()时,由于C()函数中只是定义了一个私有变量var n=8888,并没有为对象执行任何操作,也就是说这个变量属性没有绑定到new出来的对象c上,所以c实例中不存在名字为n的属性。因此,c.n会访问原型中的n属性。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值