JS开发新手:
ES3基本语法, 递归, 表达式优先级, 隐式转换, 声明前置, IIFE, 作用域链, 闭包, ES5数组
递归
含义
递归函数:递归函数就是在函数体内调用本函数。
缺点:
1.如果递归函数的终止条件不明确或者缺少终止条件会导致函数长时间运行,是用户界面处于假死状态。
2.浏览器对递归的支持熟练与JS调用栈大小相关,使用太多递归甚至超过最大调用栈容量时,浏览器会报错。
经典的递归阶乘函数
function test(num){
if(num <= 1){
return 1;
}else{
return num * test(num-1);
}
}
var f = test;
test = null;
console.log(f(2));//报错 Uncaught TypeError: test is not a function
当调用f()函数时,而test已经不再是一个函数了,所以会导致错误,但是我们可以使用arguments.callee来解决这个问题。但是在严格模式arguments.callee会错。
解决方案:
var fs = (function test(num){
if(num <= 1){
return 1;
}else{
return num * test(num-1);
}
//下面这两行代码完全不会影响运行
var f = test;
test = null;
});
console.log(fs(2));
即使函数赋值给了另外一个变量,f()函数依然是有效的,所以递归调用能正常完成。而且这种方式在严格模式和非严格模式下都可以使用
表达式优先级
隐式转换
1、.toString()可以将所有的的数据都转换为字符串,但是要排除null 和 undefined
.toString() 括号中的可以写一个数字,代表进制,对应进制字符串
二进制:.toString(2);
八进制:.toString(8);
十进制:.toString(10);
十六进制:.toString(16);
2、网页代码String()可以将null和undefined转换为字符串,但是没法转进制字符串
递增递减运算符(前置、后置)
JavaScript运算符中的隐式转换规律:
一、递增递减运算符(前置、后置)
1.如果包含的是有效数字字符串或者是有效浮点数字符串,则会将字符串转换(Number())为数值,再进行加减操作,返回值的类型是:number类型。
2.如果不包含有效数字字符串,则会将字符串的值转换为NaN,返回值的类型是:number类型。
3.如果是boolean类型,则先会把true或者false转换为1或者0,再进行加减操作,返回值的类型是:number类型。
4.如果是null类型,则先会把null转换为0,在进行加减操作,返回值的类型是:number类型。
5.如果是undefined,则先会把undefined转换为NaN,再进行加减操作,返回值的类型是:number类型。
6.如果是对象,则先会通过对象的valueOf()方法,进行转换,如果返回的是NaN,调用toString()方法,在进行前面的操作,返回值的类型是:number类型。(注:空数组[]会返回0,在进行加减操作,空对象则会返回NaN)。
二、逻辑操作符中的隐式转换规律(注:只有undefined、null、NaN、0、空字符串会被转换为false,其余都为true):
逻辑操作符一般用于语句判断中。通过判断结果返回的值进行后面的语句操作。
1.逻辑非(!)操作符:首先会通过Boolean()函数将其操作值转换为布尔值,然后求反。
2.逻辑与(&&)操作符:如果第一个值经过Boolean()函数转换后为true,则返回第二个操作值,否则返回第一个操作值。如果有一个操作值为null这返回null,如果有一个操作值为undefined,则返回undefined,如果有一个值为NaN,则返回NaN。
3.逻辑或(||)操作符:如果第一个值经过Boolean()函数转换为false,则返回第二个操作值,否则返回第一个操作值。
(注:逻辑操作符的运算为短路逻辑运算:前一个条件已经能够得出结果后续条件不再执行!)
三、关系操作符的隐式转换规律(关系操作符的操作值也可以是任意类型):
1.如果两个操作值都是数值,则直接比较大小。
2.如果两个操作值都是字符串,则字符串进行其Unicode编码进行比较。
3.如果一个操作值是数值,则另一个值转换为数值进行比较。
4.如果一个操作值是对象,则调用对象的valueOf()和toString()方法,然后再进行上述比较。
5.如果一个操作值是布尔值,则将布尔值转换为数值再进行比较。
(注:NaN和任何值都不相等,包括自己,同时它与任何类型比较都会返回false。)
相等操作符==和===的隐式转换规律:
1.布尔值、字符串和数值进行比较,会先将其转换为数值再进行比较。
2.null和undefined比较是相等的,但不是全等的。
3.NaN与任何值都不相等,都会返回false。
显式转换
1.做显示类型转换最简单的方法就是用Boolean()、Number()、String()或Object()函。
2.x+”” //等价于String(x)
+x //等价于Number(x)
x-0 //同上
!!x //等价于Boolean(x),是双叹号
IIFE
最常用的两种办法
(function(){ /* code */ }());
(function(){ /* code */ })();
其他写法
var i = function(){ return 10; }();
true && function(){ /* code */ }();
0, function(){ /* code */ }();
!function(){ /* code */ }();
~function(){ /* code */ }();
-function(){ /* code */ }();
+function(){ /* code */ }();
new function(){ /* code */ };
new function(){ /* code */ }();
作用域
对于IIFE来说,通过作用域链来查找变量与普通函数有一些不同的地方
IIFE用途
用于构造私有变量,避免全局空间污染
注意:
var a = function(){
return 1;
}
(function(){
console.log(a());//报错
})();
原因:
函数有一个声明提升的过程,函数表达式其实分为先声明后赋值这两步。而,如果后面存在着立即执行函数IIFE,这个IIFE会快到函数表达式a执行完第一步骤函数声明之后IIFE就会立即执行,这此时a未被赋值,是undefined,所以执行a()时会报错