问题1:作用域(Scope)
思考以下代码:
(function(){
var a=b=5;
})();
console.log(b);
控制台(console)会打印出什么?
答案
上述代码会打印出5
.
这个问题的陷阱就是,在立即执行函数表达式(IIFE)中,有两个赋值,但是其中变量a
使用关键词var
来声明.使用var
声明变量,在方法内部是局部变量,在方法外部是全局变量.与此相反,b
被分配给了全局作用域,也就是全局变量.
这个问题的另一个陷阱就是,在函数没有使用'严格模式'('use strict').如果严格模式开启,那么代码就会报错.
问题2:创建'原生'(native)方法
在
String
对象上定义一个repeatify
函数.这个函数接受一个整数参数,来明确字符串需要重复几次.这个函数要求字符串重复指定的次数.举个例子:console.log("hello",repeatify(3));
应该打印出hellohellohello
.
答案
String.prototype.repeatify = String.prototype.repeatify || function(times){
var str = '';
for(var i=0;i<times;i++){
str+=this;
}
return str;
};
问题3:变量提升(Hoisting)
function test(){
console.log(a);
console.log(foo());
var a = 1;
function foo(){
return 2;
}
}
test();
答案
这段代码的执行结果是undefined
和2
.
这个结果的原因是,变量和函数都被提升到了函数体的顶部.因此,当打印变量a
时,它虽存在于函数体,但仍然是undefined
.换言之,上面的代码等同于下面的代码:
function test(){
var a;
function foo(){
return 2;
}
console.log(a);
console.log(foo());
a = 1;
}
test();
问题4:在javascript中,this是如何工作的
var fullname = 'John Doe';
var obj ={fullname:'Colin Ihrig',prop:{fullname:'Aurelio De Rosa',getFullname:function(){return this.fullname;}}};
console.log(obj.prop.getFullname());
var test = obj.prop.getFullname;
console.log(test());
答案
这段代码打印结果是:Aurelio DeRosa
和John Doe
.原因是,javascript中关键字this
所引用的是函数上下文,取决于函数是如何调用的,而不是怎么被定义的.
在第一个console.log()
,getFullname()
是作为obj.prop
对象的函数被调用.因为,当前的上下文指代后者,并且函数返回这个对象的fullname
属性.相反,当getFullname()
被赋值给test
变量时,当前的上下文是全局对象window
,这是因为test
被隐式的作为全局对象的属性.基于这一点,函数返回window
的fullname
,在本例中即为第一行代码设置的.