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¶m2=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