一,
javascript 代码效果预览
答案为
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);
思路解析:
a: undefined,0,0,0
b: undefined,0,1,2
c: undefined,0,1,1
var a = fun(0); a.fun(1); a.fun(2); a.fun(3);
1,fun(0) 时,第一个参数 n 为 0,第二个参数 o 未设置,console.log(o) 为 undefined,return 值为:
2,a.fun(1);m=1,代入上方 return,得出新的 return 值为 fun(1,0),执行得出 console.log(0),return 值为:
{
fun:function(m){
return fun(m,n); //n 为 0
}
3,a.fun(2);m=2,同理代入上方 return,得出新的 return 值为 fun(2,0),执行得出 console.log(0),return 值为 fun(3,0);
//fun(1,0) return 值为:
{
fun:function(m){
return fun(m,n); //n 为 0
}
4,a.fun(3);m=3 同理, 代入上方 return,得出新的 return 值为 fun(3,0),执行得出 console.log(0).
var b = fun(0).fun(1).fun(2).fun(3);
1,与前面 a 一样, 当执行到 fun(0) 时,第二个参数未设置,console.log(o) 为 undefined;
2,当执行到 fun(0).fun(1) 时,m 为 1,代入 return,得出新的 return 值为 fun(1,0),执行 fun(1,0),console.log(0),return 值为 fun(1,1);
3,当执行到 fun(0).fun(1).fun(2) 时,m 为 2,代入 return,得出新的 return 值为 fun(2,1),执行 fun(2,1),console.log(1),return 值为(2,2)
4,当执行到 fun(0).fun(1).fun(2).fun(3) 时,m 为 3,代入 return,得出新的 return 值为 fun(3,2),执行 fun(3,2),console.log(2);
var c = fun(0).fun(1); c.fun(2); c.fun(3);
1,当 fun(0) 时,与前面 b 一致,undefined;
2,当 fun(0).fun(1) 时,与前面 b 一致,console.log(0),得出新的 return 值为 fun(1,1)
因此 c.fun(2) 就是 fun(0).fun(1).fun(2),与前面 b 一致,console.log(1);
因此 c.fun(3) 就是 fun(0).fun(1).fun(3),m=3,代入 return,得出新的 retrun:fun(3,1),得出结果 console.log(1)
二,
javascript 代码效果预览
答案为:5 5 5 5 5
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 0);
}
思路解析::
这个定时器里面有个匿名函数且有闭包, 要打印 i 此时调用了它外面的循环的 i, 当循环结束后才打印出 i, 所以 i 每次都是打印最后那个循环结束的最新值 5
三,
javascript 代码效果预览
答案为:456
var a={};
var b={key:'b'};
var c={key:'c'};
a[b]=123; // toString = [object Object]
// console.log(a); //{[object Object]: 123}
a[c]=456;
console.log(a[b]); //456
思路解析:
现在 a 变量中有两个属性 [b] 和 [c](因为只有字符串才可以做属性名),它们在通过 [] 访问对象属性时, 方括号中的表达式将会被求值并被通过调用它的 toString 方法转换成一个字符串. 此时 toString = [object Object], 即这里的 a[b]=123 和 a[c]=456 分别转换成了 a['[object Object]'] = 123 和 a['[object Object]'] = 456, 所以再次赋值就会被覆盖
四,
javascript 代码效果预览
答案为:a :undefined
(function(){
var a = b = 3;
})();// 函数自调
console.log("a :" + typeof a);//a :undefined
console.log("b :" + typeof b);//b : number
b :number
思路解析:
因为在闭包中 var 声明的是局部变量,所以这里的 a 是局部变量,而 b 没有用 var 声明,所以在闭包中 b 自动变成全局变量,那因此打印的时候,由于 a 在这个函数的外面是没有声明而无法找到, 而 b 在闭包里面 b=3 赋值了,所以输出 b 的类型是 number
五,
javascript 代码效果预览
答案为:2 4 1 1 2 3 3
function Foo() {
getName = function () { alert (1); };
return this;
}
// 静态方法 只能通过 Foo. 方法名 ()
Foo.getName = function () { alert (2); };
Foo.prototype.getName = function () { alert (3); };
var getName = function () { alert (4); };
function getName() { alert (5); }
Foo.getName(); // 2
getName(); // 4
Foo().getName(); // 1
getName(); // 1
new Foo.getName(); // 2
new Foo().getName(); // 3
new new Foo().getName(); // 3
思路解析:
从题目来看,getName 分别以变量,和函数变量的形式声明,涉及到变量声明提前.因此实际执行是:
1,因此 Foo.getName() 调用时,首先访问静态属性,所以返回 2;
function Foo() {
getName = function () { alert (1); };
return this;
}
var getName;// 只提前变量声明
function getName() { alert (5);}// 覆盖 var 的声明
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
getName = function () { alert (4);};
2,getName(); 变量声明提前,函数声明提前,函数覆盖变量声明,所以返回 4;
3,Foo().getName(); 执行第一个函数返回的 this,Foo 函数中赋值一个全局变量 getName=function(){alert(1)},当前作用域没有 getName,因此会向上层寻找 window,覆盖外面的 getName 的定义,返回一个 1,.同时这时也改变了全局变量,this 指向了 window,相当于 window.getName;
4, getName(); 由于前面已经将全局变量给替换掉了,所以直接调用 getName();
5,new Foo.getName() 相当于 new(Foo.getName)(),这里注意运算符优先级,new 一个 (Foo.getName),即 new 了一个静态方法里的 Foo.getName 对象,就返回了 2 .这里运用了运算符优先级,其级别表示分别为:
圆括号 ()> 成员访问 > new 带参数列表 > 函数调用 > new 不带参数列表 > 递增递减 > 逻辑运算符 > 一元加法减法 > typeof > 算数 > 位移 > 比较 > in,instance > 条件,赋值,逗号
6,(new Foo()).getName(); 是关于返回值的问题.在构造函数中,返回值可以没有返回值,有返回值的时候检查是不是引用类型,是基本类型等于 undefined,实例里返回实例化对象,是引用类型的时候返回 undefined,实例返回这个引用类型.这里返回了 this 是实例化对象,没有 getName 属性,通过原型链找到构造函数的原型对象为 3;
7,new new Foo().getName(); 等价于 new ((new Foo()).getName)(),所以也是返回 3
六,
javascript 代码效果预览
答案为:441
function ClassA(){
var value = 4;
this.getValue = function (){
return value;
}
this.setValue = function (value){
this.value = value;
}
}
var classa = new ClassA();
document.write(classa.getValue()); // 4
classa.setValue(1); // 给对象 classa 添加了一个属性 value 他的是 1
document.write(classa.getValue()); // 4
document.write(classa.value); // 1
思路解析:
1,在这里的 this.value 其实是原型变量,在 classA 函数内部定义为 classA.prototype.value,它 与 var value 是两个不同的变量.
2,这里第一个和第二个 classa.getValue() 其实都是输出的 var value=4 这个值,而第三个 classa.value 其实输出的是 this.value 的值,因为这个值已经被 setValue 赋值为 1 了.
3,this.value 和 var value=4 这个 value 是两个不同的变量, 而 this.value 和 (classa.value 和 (classa.prototype.value 是同一个变量
来源: http://www.qdfuns.com/notes/48922/c6db8a501e1a715ec6f336e1f8115b78.html