面试题

168 阅读6分钟

JavaScript 中,定义函数时用 var foo = function () {} 和 function foo() 有什么区别?

最关键的区别在于JavaScript 函数和变量声明的“提前”(hoist)行为。
the Google style guide 建议我们采用方法一。

简单的说 如果我们使用 匿名函数
var FUNCTION_NAME = function() { /* FUNCTION_BODY */}; 
这种方式, 编译后变量声明FUNCTION_NAME 会“被提前”了,但是他的赋值(也就是FUNCTION_BODY)并不会被提前。
也就是,匿名函数只有在被调用时才被初始化。

如果我们使用 
function FUNCTION_NAME () { /* FUNCTION_BODY */}; 
这种方式, 编译后函数声明和他的赋值都会被提前。
也就是说函数声明过程在整个程序执行之前的预处理就完成了,所以只要处于同一个作用域,就可以访问到,即使在定义之前调用它也可以。
// TypeError: functionOne is not a function
functionOne();

var functionOne = function() {
  console.log("Hello!");
};
// Outputs: "Hello!"
functionTwo();

function functionTwo() {
  console.log("Hello!");
}

声明提升

函数 > 变量

   var a=10;
      function fun(){
          console.log(a); //undefined var a 声明提前,赋值不提前,所以空
          var a=100;
          console.log(a); //100 var a=100 有赋值
      }
      fun(); //运行了fun函数
误以为函数fun的第一个console会输出10,因为代码此时还没有执行到var语句声明局部变量的代码行。

其实不然,由于函数作用域的特性,局部变量在整个函数体内始终是有定义的,亦即,在函数体内局部变量覆盖了同名的全局变量。尽管如此,只有程序执行到var语句时,局部变量才会被赋值。因此上述过程等价于,将函数体内的变量声明“提前”至函数体顶部,而变量的初始化保留在原处。

基于此原因,建议将变量的声明都放在作用域的顶部(全局代码的顶端,或者函数代码的开始),从而清楚地区分变量的作用域,哪些是函数作用域,哪些在作用域链上解析。

什么是jsonp?请详细说明其原理,并解释为什么这种方式存在安全性问题,怎样避免这种安全性问题?

jsonp定义:

是一种非正式传输协议,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
形如:<script src="http://www.example.net/api?param1=1&param2=2&callback=_t"></script> 

存在安全性问题的原因:

jsonp的漏洞在于callback函数,它可以植入脚本影响后端代码。
JSONP 安全攻防技术里面介绍了在使用jsonp存在的安全性问题,
一方面是json挟持,另一方面是callback植入脚本的漏洞。
解决漏洞的方法可以在头文件中加上Content-Type:application/json,
但是在老版本的ie还是会出现编码安全问题,还需要限制编码charset=utf-8。

json与jsonp的区别

json是一种数据格式。 jsonp是一种非官方跨域数据交互协议

Es6中let、const跟var有什么不同,请尽可能详细说明

参考

一、var 声明
    1、存在变量提升,实际上var无论在哪里声明,都会被当做当前的作用域顶部声明变量
    2、可以重复声明,后声明的变量会覆盖前声明的变量

二、let 声明
    1、不存在变量提升
    2、禁止重复声明
    3、块级作用域,只在当前作用域块有用
    4、临时死区,而且不能在声明之前访问它
三、const 声明
    1、const 声明的是常量,其值一旦确定后不可以修改
    2、const 声明常量时候必须要进行赋值
    3、const 不存在变量提升,一旦执行快外就会立即销毁
    4、const 只能在当前代码块级有效
    5、const 不能重复声明相同常量
    6、const 声明不允许修改绑定,但允许修改值,也就是说可以修改该对象的属性值

请尽可能详细描述你对使用过的前端JS狂街的理解,例如AngularJS、react、vue等

如何通过异步的方式避免发规模计算引起的前端无响应?请分别用Promise、Generator、Async/Await改写下面一段例子

var tasks = [];
for(){
    performs(tasks[i])  //performs is a synchromous function
}

值得注意的是,await必须在async函数的上下文中的。

const sleep = time => {
    return new Promise( (resolve, reject) => {
        setTimeout( () => {
            resolve();
        }, time);
    })
};
(async function () {
    for (var i = 1; i <= 10; i++) {
        console.log(`当前是第${i}次等待..`);
        await sleep(1000);
    }
})();

undefined、null、NaN

NaN

  • 在JavaScript中,有6大数据类型,分别包括string,number,boolean,undefined,null和object, 而对于JS来说,整数和浮点数都统称为number类型,除此之外,number类型还有一个很特殊的值,即NaN, 它是用来表示是否属于number类型的一种状态: 是或否。而不是一个确切的值。

    (1) 一个表达式中如果有减号(-)、乘号(*) 或 除号(/) 等运算符时,JS引擎会在计算之前试图将运算符两边的变量转化为number类型,如果转化失败,表达式将返回NaN

    (2) 直接使用 parseInt, parseFloat 或 Number将一个非数字的值转化为数字时,表达式返回NaN

    如果非要说NaN是一个值得话,那么 NaN 就是除过数字的任意值,但绝不是确切的某一个值! 所以 NaN != NaN , 因为它是一个范围,而不能代表一个确定的值

  • 此之外,与NaN相关的还有一个函数,即 isNaN() , 它是用来判断某一个变量是不是数字或能否转化为数字,仅此而已。

undefined

  • undefined是JavaScript中6种数据类型中的一种,该类型只有一个值,也就是undefined。 undefined意为未定义,即当使用var声明了变量但未进行赋值时,这个变量的值就是undefined。undefined产生的原因有两种:

    (1)访问对象不存在的属性或方法

    (2)声明了变量但从未赋值

    typeof undefined;// "undefined"

    varv1,obj = {};
    
    console.log(v1);//undefined
    
    console.log(obj.get);//undefined
    
    typeofv1;// "undefined"
    
    typeofv2;// "undefined"
    
    typeofobj.get;// "undefined"
    
  • 和NaN不同的是,undefined虽然也代表变量的一个状态,但这个状态值是确定唯一的,即当一个变量声明了但没有赋值时,它的状态就是undefined,因此下面表达式是成立的:

    var b;
    
    b == undefined;//true
    

null

  • 理解了undefined以后,再理解null就容易多了,null类型也只有一个值:null , 表示一个变量中没有包含有效数据。null在这里意为空值、空对象的意思,更确切的说,一个被赋值为null的变量没有保存有效的数值、字符串、布尔、数组或对象等,可以通过给一个变量赋值为null来清空变量中的内容。产生null的原因只有一个:即对一个变量显式的赋值为null 。

    typeof null;// "object",这就是由于历史的原因

    var p = null;
    
    console.log(p);//null
    
    typeof p;// "object"
    
    typeof null;// "object"
    
  • 还是和NaN来比较,null也是一个确定切唯一的状态值,当一个变量被赋值为null时,那么它就和null相等,因此下面表达式也是成立的:

    var obj = null;
    
    obj == null;//true
    
  • 要记住null == undefined