一、数组相关(续)
1. 返回数组中和target相同的值的索引
(1)
可以用reduce()/map()等,但是注意,indexOf(x)返回的是元素在数组中的第一个位置。
(2)|| 短路语法巧用
啊,不得不说,广大人民的智慧是无穷的,又学到了一项新技巧。
function findAllOccurrences(arr, target) {
var temp = [];
arr.forEach(function(val,index){
val !== target || temp.push(index);
});
return temp;
}
二. 变量提升(变量声明和函数声明)
真的是要做做题才真的知道自己哪里不会,在书上看过的内容不这样在题里遇到还真的不知道原来自己没有真正理解。
题目要求:
改正题目中的问题,使得例如输入true的时候输出a:
function functions(flag) {
if (flag) {
function getValue() { return 'a'; }
} else {
function getValue() { return 'b'; }
}
return getValue();
}
这里涉及到的问题就是函数声明的提升。题目给的代码相当于↓
function functions(flag) {
function getValue() { return 'a'; }
function getValue() { return 'b'; }
if (flag) {}
else {}
return getValue();
}
在JS中, 变量有4种基本方式进入作用域:
- 语言内置: 所有的作用域里都有this和arguments;(需要注意的是arguments在全局作用域是不可见的)
- 形式参数: 函数的形式参数会作为函数体作用域的一部分;
- 函数声明: eg: function foo() {};
- 变量声明: eg: var foo;
函数的提升
我们写JS的时候,通常会有两种写法:
- 函数表达式 var fn=function fn(){}
- 函数声明方式 function fn(){}
只有函数声明形式才能被提升。函数体也会一同被提升。函数声明提升直接把整个函数提到执行环境的最顶端。
而函数表达式的提升则只是提升了变量声明,赋值没有被提升。
而变量声明的提升则是:
- 变量声明var a;会被提升到顶端。
- 初始化的变量声明则不会被提升。例如var a= 10;则不会被提升到顶部。在此语句之前对a进行操作则会输出undefined(未定义)。
函数优先,虽然函数声明和变量声明都会被提升,但是函数会首先被提升,然后才是变量。并且,函数声明的优先级比变量声明的优先级高。
eg:
function text6() {
function a() {}
var a;
log(a); //打印出a的函数体
var b;
function b() {}
log(b); //打印出b的函数体
var c=10;
function c() {}
log(c); //打印出10, 相当于变量c先被声明为函数体,然后又被赋值了10
}
再举一个栗子:
function text() {
var a = 1;
function b() {
a = 10;
return;
function a() {}
}
b();
log(a); // 最终打印出来1
}
这段代码相当于:
function text6() {
function b() {
var a=function a() {};
a = 10;
//此时a=10,但是注意!!这个a和外面的a不一样,它是个b()中的内部变量。
return;
}
var a = 1;
b();
log(a); //所以这里b()的执行并不影响a的值。输出1
}
所以这道题可以改为:
function functions(flag) {
if (flag) {
var getValue =function () { return 'a'; }
} else {
var getValue=function() { return 'b'; }
}
return getValue();
}
当然这就相当于:
function functions(flag) {
var getValue;
if (flag) {
getValue =function () { return 'a'; }
} else {
getValue=function() { return 'b'; }
}
return getValue();
}
三、 parseInt()
- parseInt()函数在转换字符串时,会忽略字符串前后的所有空格,直到找到第一个非空格字符。
- 如果第一个字符不是数字或者负号,parseInt() 就会返回NaN,同样的,用parseInt() 转换空字符串也会返回NaN。
- 如果第一个字符是数字字符,parseInt() 会继续解析第二个字符,直到解析完所有后续字符串或者遇到了一个非数字字符。
- parseInt()方法还有基模式,可以把二进制、八进制、十六进制或其他任何进制的字符串转换成整数。基是由parseInt()方法的第二个参数指定的,所以要解析十六进制的值,当然,对二进制、八进制,甚至十进制(默认模式),都可以像这样调用parseInt("132",16)方法。
- 注:如果radix不是数值,会被自动转为一个整数。这个整数只有在2到36之间,才能得到有意义的结果,超出这个范围,则返回NaN。如果第二个参数是0、undefined和null则直接忽略。
- 第二个参数radix省略时,默认为10进制解析,以0x开头时以16进制解析。以0开头时按照10进制解析。
- 自动转为科学计数法的数字,parseInt会将科学计数法的表示方法视为字符串。如:
parseInt(1000000000000000000000.5) // 1, 等同parseInt('1e+21')
parseInt(0.0000008) // 8, 等同于parseInt('8e-7')
同样的还有Number()和parseFloat():
Number():
- Boolean值,则true和false值将分别被转换为1和0。
- 数字值,只是简单的传入和返回。
- null值则返回0。
- undefined,返回NaN。
- 字符串:
- 如果字符串中只包含数字时,将其转换为十进制数值,忽略前导0
- 如果字符串中包含有效浮点格式,如“1.1”,将其转换为对应的浮点数字,忽略前导0
- 如果字符串中包含有效的十六进制格式,如“0xf”,将其转换为相同大小的十进制数值
- 如果字符串为空,将其转换为0
- 如果字符串中包含除上述格式之外的字符,则将其转换为NaN
- 对象,则调用对象的valueOf()方法,然后依照前面的规则转换返回的值。如果转换的结果是NaN,则调用对象的toString()方法,然后再依照前面的规则转换返回的字符串值。
parseFloat():
- parseFloat() 也是从第一个字符(位置0)开始解析每一个字符。也是一直解析到字符串末尾,或者解析到遇见一个无效的浮点数字字符为止。
也就是说,字符串中第一个小数点是有效的,而第二个小数点就是无效的了,它后面的字符串将被忽略。 - parseFloat() 只解析十进制,因此它没有第二个参数指定基数的用法。所以遇到十六进制数时,一定会返回0。
- 如果字符串中包含的是一个可解析为正数的数(没有小数点,或者小数点后都是零),parseFloat() 会返回整数。
就快考密码学和信息论了,慌的一批,田大师的课真的听不懂啊。。。