博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
五个典型的JavaScript面试题
阅读量:6309 次
发布时间:2019-06-22

本文共 2493 字,大约阅读时间需要 8 分钟。

问题1: 范围(Scope)

  思考以下代码:

1
2
3
4
5
(
function
() {
   
var
a = b = 5;
})();
 
console.log(b);

  控制台(console)会打印出什么?

  答案

  上述代码会打印出5。

  这个问题的陷阱就是,在立即执行函数表达式(IIFE)中,有两个命名,但是其中变量是通过关键词var来声明的。这就意味着a是这个函数的局部变量。与此相反,b是在全局作用域下的。

  这个问题另一个陷阱就是,在函数中他没有使用"严格模式" ('use strict';)。如果 开启,那么代码就会报出未捕获引用错误(Uncaught ReferenceError):b没有定义。记住,严格模式要求你在需要使用全局变量时,明确地引用该变量。因此,你需要像下面这么写:

1
2
3
4
5
6
(
function
() {
   
'use strict'
;
   
var
a = window.b = 5;
})();
 
console.log(b);

 问题2: 创建 “原生(native)” 方法

  在String对象上定义一个repeatify函数。这个函数接受一个整数参数,来明确字符串需要重复几次。这个函数要求字符串重复指定的次数。举个例子:

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

  应该打印出hellohellohello.

  答案

  一种可能的实现如下所示:

1
2
3
4
5
6
7
8
9
String.prototype.repeatify = String.prototype.repeatify ||
function
(times) {
   
var
str =
''
;
 
   
for
(
var
i = 0; i < times; i++) {
      
str +=
this
;
   
}
 
   
return
str;
};

  这个问题测试了开发人员对于javascript中继承的掌握,以及prototype这个属性。这也验证了开发人员是否有能力扩展原生数据类型的功能(虽然不应该这么做)。

  这个问题的另一个重点是验证你是否意识到并知道如何避免覆盖已经存在的函数。这可以通过在自定义函数之前判断该函数是否存在来做到。

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

  当你需要为旧浏览器实现向后兼容的函数时,这一技巧十分有用。

 问题3: 变量提升(Hoisting)

  执行以下代码会有什么结果?为什么?

1
2
3
4
5
6
7
8
9
10
11
function
test() {
   
console.log(a);
   
console.log(foo());
 
   
var
a = 1;
   
function
foo() {
      
return
2;
   
}
}
 
test();

  答案

  这段代码的执行结果是undefined 和 2。

  这个结果的原因是,变量和函数都被提升了()。因此,在a被打印的时候,它已经在函数作用域中存在(即它已经被声明了),但是它的值依然是 undefined。换言之,上述代码和以下代码是等价的。

1
2
3
4
5
6
7
8
9
10
11
12
13
function
test() {
   
var
a;
   
function
foo() {
      
return
2;
   
}
 
   
console.log(a);
   
console.log(foo());
 
   
a = 1;
}
 
test();

 问题4: this在javascript中是如何工作的

  以下代码的结果是什么?请解释你的答案。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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 De Rosa和John Doe。原因是在 JavaScript 中,一个函数的上下文环境,也就是this关键词所引用对象,是依赖于函数是如何被调用的,而不是依赖于函数如何b被定义的。

  在第一个console.log()调用中, getFullname()是作为obj.prop的函数被调用的。因此,这里的上下文环境指向后者并且函数返回this对象的 fullname属性。相反,当 getFullname() 被赋为test变量的值时,那个语境指向全局对象(window)。这是因为,test被隐式设置为全局对象的属性。因此,函数调用返回window的fullname属性值,在此段代码中,这个值是通过第一行赋值语句设置的。

 问题5: call() 和 apply()

  修复上一个问题,让最后一个console.log()打印出 Aurelio De Rosa。

  答案

  要解决这个问题,可以通过为函数call()或者apply()强制函数调用的上下文环境。如果你不知道call()和apply()之间的区别,我推荐阅读文章。在以下代码中,我会用call(),但是在这里,用apply()也可以获得相同的结果:

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

转载于:https://www.cnblogs.com/huenchao/p/6168386.html

你可能感兴趣的文章
ReferenceError: event is not defined
查看>>
男人要内在美,更要外在美
查看>>
为什么要跟别人比?
查看>>
app启动白屏
查看>>
Oracle 提高查询性能(基础)
查看>>
学习知识应该像织网一样去学习——“网状学习法”
查看>>
Hadoop集群完全分布式安装
查看>>
QString,char,string之间赋值
查看>>
我的友情链接
查看>>
Nginx+mysql+php-fpm负载均衡配置实例
查看>>
shell脚本操作mysql数据库 (部份参考)
查看>>
MySql之基于ssl安全连接的主从复制
查看>>
informix的逻辑日志和物理日志分析
查看>>
VMware.Workstation Linux与windows实现文件夹共享
查看>>
ARM inlinehook小结
查看>>
wordpress admin https + nginx反向代理配置
查看>>
管理/var/spool/clientmqueue/下的大文件
查看>>
HTML学习笔记1—HTML基础
查看>>
mysql dba系统学习(20)mysql存储引擎MyISAM
查看>>
centos 5.5 64 php imagick 模块错误处理记录
查看>>