动漫引擎

导航

JS面试典型常见问题与解答

 

Q1:下面代码段的输出是什么? 为什么? (Scope)

(function() {

   var a = b = 5;

})();

console.log(b);

 

A1: 输出是5.

 

在上面的立即调用函数表达式(IIFE----Immediately Invoked Function Expression)中,

变量a是用var定义的局部变量, 变量b没有定义, 所以系统就自动定义它为全局变量。

 

 

所以,变量b的值会一直保存, 并被IIFE之后的log语句使用

 

追问:在严格模式(use strict),上面的代码会导致Uncaught ReferenceError. 为什么? 如何改。

 

A: 因为 在strict 模式下必须显式地引用全局变量,把b写成window.b

修改后如下:

(function() {

   'use strict';

   var a = window.b = 5;

})();

console.log(b);

 

 

Q 2: 为String对象添加1个函数repeatify(n), n是整数,n>0,函数返回一个字符串,重复n遍本字串的内容。例如:

console.log('hello'.repeatify(3));

返回 hellohellohello.

A2:

String.prototype.repeatify = String.prototype.repeatify || function(times) {

   var str = '';

   for (var i = 0; i < times; i++) {

      str += this;

   }

   return str;

};

答案要点:

  • 继承和prototype.
  • 拓展内置的元素类别.
  • 这是好习惯:总是尽量避免覆盖已有函数, 通过如下形式的测试:

String.prototype.repeatify = String.prototype.repeatify || function(times) {/* code here */};

 

Q 3:变量和函数的声明自动提前(hoisting)

下面代码段的执行结果是什么? 为什么?

function test() {

   console.log(a);

   console.log(foo());

   var a = 1;

   function foo() {

      return 2;

   }

}

 

test();

A:执行结果如下:

undefined 

2

变量和函数的声明都会提前到函数的顶部,但是,变量的赋值不提前,所以,log(a)的时候,这个变量a是声明了,但是没有赋值, 是 undefined.

function test() {

   var a;  // 变量的声明被提前到函数的顶部,

   function foo() { //函数的声明被提前到函数的顶部,

      return 2;

   }

   console.log(a);

   console.log(foo());

   a = 1;  // 变量的赋值, 不会被提前,留在了原地

}

test();

 

Q4:下面代码段的执行结果是什么? 为什么?(this的含义)

var fullname = '张三';

var obj = {

   fullname: '李四',

   prop: {

      fullname: '王五',

      getFullname: function() {

         return this.fullname;

      }

   }

};

console.log(obj.prop.getFullname());

var test = obj.prop.getFullname;

console.log(test());

A:执行结果是:

王五

张三

原因是this所指的内容, 取决于函数调用时的上下文,而不是定义时的内容。

在通过obj.prop.getFullname()调用的时候, 函数getFullnanme()是当作obj.prop对象的一个函数, 所以它的上下文是prop对象,函数里面的this就指向obj.prop对象,所以, this.getFullname()就是obj.prop的局部变量,王五;

在通过test()调用的时候, getFullname 被赋值给了变量 test,test是全局对象windows的属性,所以, this也就指向了windows,

Question 5: call() and apply()

Q5: 修改Q4中的最后一行代码, 使得输出为“王五” (区别call()和apply())

A5:

console.log(test.call(obj.prop));

test.call(obj.prop)把上下文obj.prop传给函数test,从而使得函数test中的this指向obj.prop.

 

也可以用apply,写成

console.log(test.apply(obj.prop));

区别在于apply以数组的形式提供其余参数,call以单列形式提供其余参数。例如:

函数func(v1, v2, v3), 用call和apply分别调用如下:

func1.apply(obj.prop, [v1, v2, v3]);

func1.call(obj.prop, v1, v2, v3);

 

posted on 2017-03-09 08:19  动漫引擎  阅读(255)  评论(0编辑  收藏  举报