9 个你可能不知道答案的常见 JavaScript 面试题。
不管你喜不喜欢,面试官在实际工作中仍然会问一些棘手的问题。
原因在于,这些问题可以反映出你对这门语言的核心理解,从而判断你是否适合这份工作。
这些问题中涉及的共同概念包括:
- 吊装
- 关闭
- 范围
- 价值型与参考型
- 原型继承
今天我们将一举两得。
立即做好准备,助您在下次面试中脱颖而出,并复习核心概念。
为什么 typeoff未定义?
var y = 1;
if (function f() {}) {
y += typeof f;
}
console.log(y); // 1undefined
解释
- 条件语句
if(function f() {})返回function f() {}真值,因此 if 语句内部的代码会执行。 typeof f返回值为空,undefined因为该函数f(){}从未在语句外部声明,所以它在括号if外部“不存在”。ifif (f(){}) { It doesn't exist here }
我们可以通过以下方式“修复”这段代码片段:
var y = 1;
function f() {}; //declare function outside if brackets
if (f) { //f exists so we enter the if block
y += typeof f; //here typeof f is function
}
console.log(y); // 1function
请举一个闭包的例子
function createFunction(msg) {
return function(name) {
return msg + name;
}
}
let myFunc = createFunction("Hey ");
console.log(myFunc("Dude")); // Hey Dude
解释
- 第一个函数(createFunction)返回一个匿名函数
- 匿名函数返回
msg外部函数(createFunction())的参数加上name自身的参数。
当我们声明变量时,javascript let myFunc = createFunction("Hey ")该变量myFunc保存着对外部函数返回的匿名函数的引用。
有趣的是,当你调用(只传递“name”参数)时,它仍然“记住”执行时传递javascript myFunc("Dude")的值。msgcreateFunction()
能够从创建函数的外部“作用域”访问变量是闭包的定义之一。
点击此处了解更多停工信息
编写一个 multiply() 函数,可以像这样调用:multiply(2)(5)(10),并返回 100。
这与上面的例子类似,区别在于我们返回了一个额外的函数,并立即调用了所有这些函数(不使用变量来保存引用)。
function multiply(x) {
return function(y){
return function(z) {
return x*y*z;
};
}
}
multiply(2)(5)(10) //100
通过像这样调用 multiply,javascript multiply(2)(5)(10)
我们将依次调用返回的函数。
我们可以使用中间变量来使其更清晰。让我们来看一下:
let func1 = multiply(2); // x is 2
console.log(func1) // function(y) { return function(z) { return x*y*z } }
let func2 = func1(5); // y is 5
console.log(func1) // function(z) { return x*y*z }
func2(10); // z is 10
// finally has all 3 values and returns their product.
点击此处了解更多关于嵌套函数的信息
delete对局部变量进行运算符
以下代码的输出结果是什么?
let output = (function(x) {
delete x;
return x;
})(0);
*删除运算符旨在用于删除对象的属性,而不是值类型(在本例中为数字)。
这样可行:
let obj = { name: 'Gus', age: 32 }
delete obj.age;
console.log(obj) // { name: 'Gus' }
delete对象上的运算符
const Person = {
name: 'Gus',
age: 32,
}
const person1 = Object.create(Person);
delete person1.age
console.log(person1.age); // 32
person1创建时,其原型已设置为该Person对象。- 当实例
person1的age属性被删除时,我们仍然可以访问age原型对象(Person)的属性。 - 这就是为什么看起来好像没成功的原因。
这是一个很大的话题,你可以在这里了解更多信息。
delete数组运算符
记录 arr.length 的结果是什么?
let arr = ["a", "b", "c", "d"];
delete arr[2];
arr.length // 4
- 当用于数组时,删除运算符会将要删除的元素设置为“空”,但不会将其从数组中移除,因此不会改变数组的长度。
console.log 的两个输出值分别是多少?
var favouriteAnime = "Dragon Ball";
(function() {
console.log(favouriteAnime);
var favouriteAnime = "Naruto";
console.log(favouriteAnime);
})();
// undefined
// Naruto
以下是编译器对这段代码的解释:
var favouriteAnime; // declared and initialized with undefined
(function() {
console.log(favouriteAnime);
var favouriteAnime = "Naruto";
console.log(favouriteAnime);
})();
favouriteAnime = "Dragon Ball";
// undefined
// Naruto
声明 JavaScript 函数和变量时需要注意以下几点。
- 变量赋值(myVar = 5)优先于函数声明(function func(){})
- 函数声明(function func(){})优先于变量声明(var myVar;)以及let 或 const
- 函数声明(function func(){})会提升到变量声明(var myVar;)之上,但不会提升到变量赋值(myVar = 5;)之上。
最佳实践是,在调用函数之前,务必先声明函数。
点击此处了解更多起重信息
如何判断一个数是否为整数?
检查一个数字是十进制数还是整数的最简单方法是使用内置函数。Number.isInteger()
console.log(Number.isInteger(4)); // true
console.log(Number.isInteger(12.2)); // false
console.log(Number.isInteger(0.3)); // false
另一种方法是看除以 1 后是否还有余数。
function isInt(num) {
return num % 1 === 0;
}
console.log(isInt(4)); // true
console.log(isInt(12.2)); // false
console.log(isInt(0.3)); // false
注意:JavaScript 处理浮点数时精度有限。如果您进行检查,Number.isInteger(1.0000000000000001)将会返回true。您可以在这里了解更多信息。
结论
记得按下 F12 键,亲自尝试一下这些示例。
这个小小的举动将帮助你更长时间地记住所学内容。
以下是今天我们所看到的内容的回顾:
- 为什么 typeof
f未定义? - 请举一个闭包的例子
- 编写一个 multiply() 函数,可以像这样调用:multiply(2)(5)(10),并返回 100。
- 对局部变量执行删除操作
- 对对象执行删除操作
- 数组删除运算符
- console.log 的两个输出值分别是多少?
- 如何判断一个数是否为整数?
感谢阅读!
如果您喜欢这篇文章:
*请在下方留言(打个招呼也行!)
*在推特上关注我@theguspear。
回头见,兄弟。
格斯。
文章来源:https://dev.to/gustavupp/9-common-javascript-interview-questions-you-might-not-know-the-answer-for-3a8g