专栏名称: Fundebug
Fundebug为JavaScript、微信小程序及Node.js开发团队提供专业的线上代码bug监控和智能分析服务。
目录
相关文章推荐
前端早读课  ·  【早阅】始终将你的估算值乘以π ·  6 小时前  
歸藏的AI工具箱  ·  终于有给设计师用的 Cursor 了 ·  2 天前  
歸藏的AI工具箱  ·  终于有给设计师用的 Cursor 了 ·  2 天前  
前端早读课  ·  【第3454期】如何用语音学习编程的 ·  2 天前  
前端大全  ·  前端行情变了,差别真的挺大。。。 ·  3 天前  
51好读  ›  专栏  ›  Fundebug

快速掌握JavaScript面试基础知识(一)

Fundebug  · 公众号  · 前端  · 2018-01-15 09:18

正文

译者按: 总结了大量JavaScript基本知识点,很有用!

  • 原文: The Definitive JavaScript Handbook for your next developer interview

为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。



根据StackOverflow调查, 自2014年一来,JavaScript是最流行的编程语言。当然,这也在情理之中,毕竟1/3的开发工作都需要一些JavaScript知识。因此,如果你希望在成为一个开发者,你应该学会这门语言。

这篇博客的主要目的是将所有面试中常见的概念总结,方便你快速去了解。
(译者按:鉴于本文内容过长,方便阅读,将分为三篇博客来翻译。)

类型和类型转换

在JavaScript中有7个内置类型: null undefined boolean number string object ,和 symbol (ES6)。

除了 object 以外,其它都叫做基本类型。

typeof 0              // number
typeof true           // boolean
typeof 'Hello'        // string
typeof Math           // object
typeof null           // object  !!
typeof Symbol('Hi')   // symbol (New ES6)
  • Null vs. Undefined

Undefined 表示未定义。对于没有初始化的变量、函数调用时候未提供的函数参数、缺失的对象属性,它们的默认值就是 undefined 。如果一个函数没有返回语句,那么默认的返回值也是 undefined

NUll 表示值为空。一个变量我们可以将其赋值为 null ,表示当前的没有值。

  • 隐式转换

请看下面的例子:

var name = 'Joey';
if (name) {
 console.log(name + " doesn't share food!")  // Joey doesn’t share food!
}

if 语句的条件判断中, name 从字符串转换为布尔型。在 if 的代码块中,在控制台将 name 原原本本打印出来。你知道在什么情况下字符串会转换为真,什么时候为假么?

"" 0 null undefined , NaN , false 会自动转换为 false 。其它的都会转换为真:

Boolean(null)         // false
Boolean('hello')      // true
Boolean('0')          // true
Boolean(' ')          // true
Boolean([])           // true
Boolean(function(){}) // true

空数组、对象、函数定义都会自动转换为真。

  • String & Number之间的转换

第一个你要非常小心的是 + 操作符。因为它同时用于数字相加和字符串拼接。

* , / , - 只用于数字运算,当这些操作符和字符串一起使用,那么字符串会被强制转换为数字。

1 + "2" = "12"
"" + 1 + 0 = "10"
"" - 1 + 0 = -1
"-9\n" + 5 = "-9\n5"
"-9\n" - 5 = -14
"2" * "3" = 6
4 + 5 + "px" = "9px"
"$" + 4 + 5 = "$45"
"4" - 2 = 2
"4px" - 2 = NaN
null + 1 = 1
  • == vs. ===

一个广泛被接受的认知就是: == 判断值是否相等, === 同时判断值是否相等和类型是否相同。但是,这里有些误解。

实际上, == 在验证相等性的时候,会对类型不同的值做一个类型转换。 === 对要判断的值不做类型转换。

2 == '2'            // True
2 === '2'           // False
undefined == null   // True
undefined === null  // False

类型转换有很多取巧的地方,要注意:

let a = '0';
console.log(Boolean(a)); // True
let b = false ;
console.log(Boolean(b)); // False
```

你认为下面的相等判断会输出什么值呢?
```js
console.log(a == b);


实际上会返回true。知道为什么吗?
如果你将一个布尔类型的和非布尔类型的判断,JavaScript会将布尔类型的转换为数字然后再比对。
执行过程如下:

'0' == false   (1)
'0' == 0       (2)
0  == 0       (3)


所以,最终变成了 0==0 ,当然返回true啦。

如果你想看完整的资料,请查看ES5的官方文档。

如果想看cheat sheet, 点击这里。

一些比较容易掉坑的比较,我在这里列出来:

false == ""  // true
false == []  // true
false == {}  // false
"" == 0      // true
"" == []     // true
"" == {}     // false
0 == []      // true
0 == {}      // false
0 == null    // false


值 vs. 引用

对于基本类型的值,赋值是通过值拷贝的形式;比如: null undefined boolean number string 和ES6的 symbol 。对于复杂类型的值,通过引用拷贝的形式赋值。比如:对象、对象包括数组和函数。

var a = 2;        // 'a' hold a copy of the value 2.
var b = a;        // 'b' is always a copy of the value in 'a'
b++;
console.log(a);   // 2
console.log(b);   // 3
var c = [1,2,3];
var d = c;        // 'd' is a reference to the shared value
d.push( 4 );      // Mutates the referenced value (object)
console.log(c);   // [1,2,3,4]
console.log(d);   // [1,2,3,4]
/* Compound values are equal by reference */
var e = [1,2,3,4];
console.log(c === d);  // true
console.log(c === e);  // false

如果想对复杂类型的值进行值拷贝,你需要自己去对所有子元素进行拷贝。

const copy = c.slice()    // 'copy' 即使copy和c相同,但是copy指向新的值
console.log(c);           // [1,2,3,4]
console.log(copy);        // [1,2,3,4]
console.log(c === copy);  // false

作用域(Scope)

作用域值程序的执行环境,它包含了在当前位置可访问的变量和函数。

全局作用域 是最外层的作用域,在函数外面定义的变量属于全局作用域,可以被任何其他子作用域访问。在浏览器中,window对象就是全局作用域。

局部作用域 是在函数内部的作用域。在局部作用域定义的变量只能在该作用域以及其子作用域被访问。

function




    
 outer() {
 let a = 1;
 function inner() {
   let b = 2;
   function innermost() {
     let c = 3;
     console.log(a, b, c);   // 1 2 3
   }
   innermost();
   console.log(a, b);        // 1 2 — 'c' is not defined
 }
 inner();
 console.log(a);             // 1 — 'b' and 'c' are not defined
}
outer();

你可以将作用域想象成一系列不断变小的门。如果一个个子不高的人可以穿过最小的门(局部最小作用域),那么必然可以穿过任何比它大的门(外部作用域)。

提升(Hoisting)

在编译过程中,将 var function 的定义移动到他们作用域最前面的行为叫做提升。

整个函数定义会被提升。所以,你可以在函数还未定义之前调用它,而不用担心找不到该函数。

console.log(toSquare(3));  // 9

function toSquare(n){
 return n*n;
}

变量只会被部分提升。而且只有变量的声明会被提升,赋值不会动。

let const 不会被提升。

{  /* Original code */
 console.log(i);  // undefined
 var i = 10
 console.log(i);  // 10
}

{  /* Compilation phase */
 var i;
 console.log(i);  // undefined
 i = 10
 console.log(i);  // 10
}
// ES6 let & const
{
 console.log(i);  // ReferenceError: i is not defined
 const i = 10
 console.log(i);  // 10
}
{
 console.log(i);  // ReferenceError: i is not defined
 let i = 10
 console






请到「今天看啥」查看全文