一道Javascript笔试题
看不到输入框和运行按钮的童鞋请直接点击标题查看原文。
Tips:You can change the code before run.
运行一下,发现结果是True的。这是为什么呢?
首先我们先确定 F()有返回值,所以这里new不能当做创建一个F对象来理解,我们先调试一下,看看这里怎么把 return C(); 在这里构成一个闭包,即返回了对C方法的引用,this 给弄走了。
Tips:You can change the code before run.
第一个alert出来的结果是F本身,第二个的结果则已经改变了。
那么我们可以先确定,return C()之后,方法C再也不是作为F的任何成员来运行了。 new 操作符作用在F上之后,返回的C方法中 this 指针不再指向F的任何实例化对象了。
这里的难点在于,这个 new 到底干了些什么事情,让 this 与其分道扬镳了呢?
这篇文章讨论的new function中有一句话:
只要 new 表达式之后的 constructor 返回(return)一个引用对象(数组,对象,函数等),都将覆盖new创建的匿名对象,如果返回(return)一个原始类型(无 return 时其实为 return 原始类型 undefined),那么就返回 new 创建的匿名对象。
我们这里的返回的是对C方法的一个引用(函数本身也是对象),由于闭包的关系,C方法并没有在创建完对象之后被GC释放掉,而是直接覆盖了 new 表达式创建的匿名对象,而我们已经将此时的C方法赋值给了某一个全局变量,即:C方法此时已经是全局变量 window 的一个方法了。
那么其中的 this 指针,理所当然就是指向 window 了。
作为对照,我们改动一下代码:
Tips:You can change the code before run.
这个例子就比较好理解了,F()方法没有 new 来干扰,直接作为全局 window 的一个方法运行,所以结果仍然是 b == window 的。
此题其实跟闭包没啥关系,我一看到返回函数的就以为是闭包,结果就直接说闭包我不熟悉……闭包还要返回的函数外有参数被返回的函数使用,这才构成闭包呢。
此题的关键在于:new function、引用对象、闭包、以及Javascript中任何东西都是对象(对象意味着引用)的理解上。
function F(){
return new function() {
this.abc = “abc”;
return this;
}
}
F.abc = ‘123′
var a = new F();
alert(a == window);
alert(a.abc)
@meteoric_cry 这个同样道理,有点变化~
new F()的结果被new function替代掉了,但也不是window,因为里面的new function已经是返回一个匿名对象,而不是像上面例子一样返回一个方法……不错
最精要的两句是:
1.只要 new 表达式之后的 constructor 返回(return)一个引用对象(数组,对象,函数等),都将覆盖new创建的匿名对象,如果返回(return)一个原始类型(无 return 时其实为 return 原始类型 undefined),那么就返回 new 创建的匿名对象。
2.C方法是window对象的一个方法
这个题的考点有两点:
1.就是你说的new的语法,当return值不是一个对象时才返回新生成的对象
2.C()方法的调用问题,当C不是某个对象的属性时,在调用C时,this指向的是global object,此处就是window
本人在想:构造函数类中的this与函数(闭包)中的this的指向有什么不同。
本人在想:构造函数类中的this与函数(作用域链)中的this的指向有什么不同。