慢慢收集一些习题、考题


练习1

问:X,Y,Z分别是多少?

var x = 1, y=z=0;
function add(n){
return n = n+1;
}
y = add(x);
function add(n){
return n = n+3;
}
z = add(x);

console.log(x); // 1
console.log(y); // 4
console.log(z); // 4

分析:考预编译的

变量提升、函数提升,同名函数覆盖;只会执行后一个函数  n = n+3 ;


练习2

问:哪些结果能输出 12345

function foo(){
bar.apply(null,arguments);
}
function bar(){
console.log(arguments);
}
foo(1,2,3,4,5); // [1,2,3,4,5]

分析:理解 apply 

apply 第一个参数改变 this 指向,这里面也没有 this ,所以 null 是什么也不做。 第二个参数把5个参数传进去。所以 foo 相当于直接执行 bar ,所以 arguments 就是结果: 12345.

(function foo(x){
console.log(arguments);
return x
})(1,2,3,4,5) // [1,2,3,4,5]

分析:理解立即执行函数

立即执行的标准写法,参数传入,输出 arguments ,还返回这些参数。

function foo(x){
console.log(arguments);
return x;
}
foo(1,2,3,4,5); // [1,2,3,4,5]

分析:函数标准调用,直接输出 arguments

function foo(x){
console.log(arguments);
return x;
}(1,2,3,4,5)

分析:函数不能执行,也不会报错,(1,2,3,4,5)当表达式处理了。


练习3

问:以下表达式结果

parseInt(3,8);   // 3
parseInt(3,2); // NaN
parseInt(3,0); // 3 或 NaN

分析:parseInt 第二个参数,二进制和八进制。

parseInt(3,8);  把3看成是八进制里的3, 输出还是3;

parseInt(3,2);  把3看成是二进制里的3,二进制里没有3,NaN;

parseInt(3,0);  没有0进制,一般浏览器会当十进制输出,即3;也有浏览器输出 NaN;

二进制: 0,1; 二进制里的2用 10表示;

八进制:0,1,2,3,4,5,6,7;八进制里的8用10表示;

十六进制: 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f; 十六进制里的16用10表示;


练习4

问:以下哪些是typeof可有返回的结果

string      //  可以
array
object // 可以
null

分析: typeof 返回结果有哪些?

7 种。分别为: string、boolean、number、Object、Function、undefined、symbol(ES6)


练习5

问:alert 的结果?

function b(x,y,a){
arguments[2] = 10;
alert(a); // 10
}
b(1,2,3);

分析:arguments 和 实参的映射关系,实参传进去,a = 3 , 先定义了 arguments[2] =10 那就等于改变了 a 的值。 所以输出 10 。

function b(x,y,a){
a = 10;
alert(arguments[2]); // 10
}
b(1,2,3);

分析:实参、形参和 arguments 是映射关系,你变我也变;除非没对应上; 所以输出 10; 

注意,形参和arguments虽是映射关系,但不是一个人;


练习6

问:输出结果

var f=(
function f(){
return "1";
},
function g(){
return 2;
}
)();
typeof f; // number

分析:“,” 逗号操作符; (1,2) 的结果就是返回2。但要用括号括起来。那么返回结果相当于是:

var f=(
function g(){
return 2;
}
)();

这又变成立即执行函数了,返回2,所以 f = 2;  typeof f 输出  number; 


练习7

问:执行结果

var x = 1;
fi(function f(){}){
x+= typeof f;
}
console.log(x); // 1undefined

分析:(function f()) 的特性是变成表达式后就执行了,执行后失去引用,就找不到了。

typeof f 的结果就变成: undefiend 了。typeof 输出的结果都是字符串类型;那么 1 + 'undefined 

' 就是 1undefined 


练习8

问:表达式结果为true的是:

undefined == null    // true
undefined === null // false
isNaN("100") // fasle
parseInt("1a") == 1; // true

分析,undefined 和 null 很特殊,有些只有硬记,看后面图。

isNaN(), 函数里面的数是要经过 Number() 隐式转换后再判断是不是“非数”的。 Number("100") = 100,数值类型的,所以 isNaN(100) == false。 

parseInt("1a")  是把字符串中的有效数字提出,转换成数值型。结果是 1 。

看下控制台:

javascript - 练习题:类型转换、预编译、作用域、闭包等_数据类型转换


练习9

问:执行结果

var foo = '123';
function print(){
var foo = '456';
this.foo = '789';
console.log(foo);
}
print(); // '456'

分析:预编译。

假如,里面没有  this.foo ,那很容易判断就是 456; 问题就在里面的 this 指向谁? window 。既然里面的 this 指向 window 了,里面就只剩下 456了。

这题改一下:

var foo = '123';
function print(){
this.foo = '789';
console.log(foo); // '789'
}
print();

分析:还是这个this的指向问题,是window,问题是 window 在外面有一个值了,在函数里面又给赋了一个新值,所以是 789。

这题再改一下:

var foo = '123';
function print(){
// var this = Object.create(print.prototype);
// var this = {
// foo : '789',
// __proto__ : print.prototype
//}
this.foo = '789';
console.log(foo); // '123'
}
new print();

分析:

这题 new 了一下,相当于把 foo 挂在了原型上。那输出的就是外面的 123。

如果这里要求输出的是  this.foo ,那输出自然就是 789了。 


练习10

问:运行 test() 和 new test() 的结果分别是什么? 

先看 test();

var a = 5; 
function test(){
a = 0;
alert(a); // 0
alert(this.a); // 5
var a;
alert(a); // 0
}
test();

分析:预编译。

主要是里面的 this.a ,当前的 this 指向 window ,window 上恰好有个 a ,是5;

再看  new test();

var a = 5; 
function test(){
// var this = {
//
// __proto__ : test.prototype
//}
a = 0;
alert(a); // 0
alert(this.a); // undefined
var a;
alert(a); // 0
}
new test();

分析: new 的话,相当于在隐式建了个 this 对象,原型指向  test.prototype ,这时的 this 对象中没有 a ,只能输出  undefined 。 


练习11

问:执行结果

function print(){
console.log(foo); // undefined
var foo = 2;
console.log(foo); // 2
console.log(hello); // 报错
}
print();

分析:预编译

第一个:预编译提升 AO 里 foo 有声明,但是没值。 所以是 undefined; 

第二个:foo 里有值了,就是2;

第三个:hello 没有声明,所以报错:  hello is not defined


练习12

问:执行结果

function print(){
var test;
test(); // 1
function test(){
console.log(1);
}
}
print();

分析:预编译

print 里的AO,var 的变量 test 被 函数覆盖,test(); 相当于直接 console.log(1); 


 练习13

 问:执行结果

function print(){
var x =1;
if(x == "1") console.log("One!"); // One1
if(x ==="1") console.log("Two!");
}
print();

分析: 数据类型转换,比较简单。  x == "1"   是 true ,“1” 被 Number()后变数值了;

x === "1"  全等的时候要考虑数据类型。所以不相等 ;


练习14

问:执行结果

var bar = {a:"002"};
function print(){
bar.a = "a";
Object.prototype.b = "b";
return function inner(){
console.log(bar.a); // "a"
console.log(bar.b); // "b"
}
}
print()();

分析:闭包,原型

print后面两个括号;先执行 print() ,把 inner() 抛出来形成闭包,根据闭包的特性,抛出来后,还可以使用原 print 函数的 AO,也就是说还可以用里面的 bra.a ,里面的 bra.a 赋了新值 “a”,所以 bra.a 输出 “a”;bra 本身没有 b 这个属性,就要向上找原型里的 b ,输出 “b”。