执行上下文
1.首先将预编译和形参定义undefined
2.将形参和实参统一
3.将函数体定义声明
<script>
function A(){
var funs=[];
for(var i=0;i<10;i++){
funs[i]=function(){
return i;
}
}
return funs;
}
var funs = A();//定义funs[0]-funs[9],10个函数
console.log(funs[0]());//10
console.log(funs[1]());//10
console.log(funs[6]());//10
</script>
当执行var funs = A();时,只是定义函数,而没有执行
真正产生环境变量的时间是在console.log(funs[0]()); 都为10
如果把var i=0改为let i=0;则打印出的结果是0 1 2 .。。。。
类型和数据操控
- Object.values()和object.keys()一个返回值,一个返回key值
- 字符填充(padStart()和padEnd()
'Vue'.padStart(10) //' Vue'
'Vue'.padEnd(10, '_*') //'Vue_*_*_*_'
- arguments
arguments.callee 调用自身正在执行的函数 用于计算乘阶4*3*2*1
arguments.callee.length获取函数要求传参的个数
arguments.callee.length获取函数要求传参的个数
- arguments类数组 argument是一个对象,只不过它的属性从0开始排,依次为0,1,2...最后还有callee和length属性
常见的类数组还有:
用getElementByTagName/ClassName/Name()获得的HTMLCollection
用querySlector获得的nodeList
- 类数组转换为数组
//Array.prototype.slice.call()
function sum(a, b) {
let args = Array.prototype.slice.call(arguments);
console.log(args.reduce((sum, cur) => sum + cur));//args可以调用数组原生的方法啦
}
sum(1, 2);//3
//Array.from() /Array.of
//array.from将对象转换为数组
//array.of(10,20,30)=>[10,20,30]
function sum(a, b) {
let args = Array.from(arguments);
console.log(args.reduce((sum, cur) => sum + cur));//args可以调用数组原生的方法啦
}
sum(1, 2);//3
//ES6展开运算符
function sum(a, b) {
let args = [...arguments];
console.log(args.reduce((sum, cur) => sum + cur));//args可以调用数组原生的方法啦
}
sum(1, 2);//3
//利用concat+apply
function sum(a, b) {
let args = Array.prototype.concat.apply([], arguments);//apply方法会把第二个参数展开
console.log(args.reduce((sum, cur) => sum + cur));//args可以调用数组原生的方法啦
}
sum(1, 2);//3
- forEach中return有效果吗?如何中断forEach循环 在forEach中用return不会返回,函数会继续执行
let nums = [1, 2, 3];
nums.forEach((item, index) => {
return;//无效
})
中断方式
- 使用try监视代码块,在需要中断的地方抛出异常。
- 官方推荐方法(替换方法):用every和some替代forEach函数。every在碰到return false的时候,中止循环。some在碰到return ture的时候,中止循环
JS判断数组中是否包含某个值
- array.indexOf
- array.includes(searcElement[,fromIndex])
返回true和false - array.find(callback[,thisArg]) 返回数组中满足条件的第一个元素的值,如果没有,返回undefined
var arr=[1,2,3,4];
var result = arr.find(item =>{
return item > 3
});
console.log(result);
- array.findeIndex(callback[,thisArg])
返回数组中满足条件的第一个元素的下标,如果没有找到,返回
-1]
var arr=[1,2,3,4];
var result = arr.findIndex(item =>{
return item > 3
});
console.log(result);
数组扁平化
多维数组=>一维数组
let ary = [1, [2, [3, [4, 5]]], 6];// -> [1, 2, 3, 4, 5, 6]
let str = JSON.stringify(ary);
- 调用ES6中的flat方法
ary = arr.flat(Infinity);
- replace + split
ary = str.replace(/(\[|\])/g, '').split(',')
- replace + JSON.parse
str = str.replace(/(\[|\]))/g, '');
str = '[' + str + ']';
ary = JSON.parse(str);
- 普通递归
let result = [];
let fn = function(ary) {
for(let i = 0; i < ary.length; i++) {
let item = ary[i];
if (Array.isArray(ary[i])){
fn(item);
} else {
result.push(item);
}
}
}
- 利用reduce函数迭代
function flatten(ary) {
return ary.reduce((pre, cur) => {
return pre.concat(Array.isArray(cur) ? flatten(cur) : cur);
}, []);
}
let ary = [1, 2, [3, 4], [5, [6, 7]]]
console.log(flatten(ary))
- 扩展运算符
//只要有一个元素有数组,那么循环继续
while (ary.some(Array.isArray)) {
ary = [].concat(...ary);
}
数组中的高阶函数
- map 参数:接受两个参数,一个是回调函数,一个是回调函数的this值(可选)。 其中,回调函数被默认传入三个值,依次为当前元素、当前索引、整个数组。
let nums = [1, 2, 3];
let obj = {val: 5};
let newNums = nums.map(function(item,index,array) {
return item + index + array[index] + this.val;
//对第一个元素,1 + 0 + 1 + 5 = 7
//对第二个元素,2 + 1 + 2 + 5 = 10
//对第三个元素,3 + 2 + 3 + 5 = 13
}, obj);
console.log(newNums);//[7, 10, 13]
- sort 一个用于比较的函数,它有两个默认参数,分别是代表比较的两个元素
let nums = [2, 3, 1];
//两个比较的元素分别为a, b
nums.sort(function(a, b) {
if(a > b) return 1;
else if(a < b) return -1;
else if(a == b) return 0;
})
当比较函数返回值大于0,则 a 在 b 的后面,即a的下标应该比b大。
反之,则 b 在 a 的后面,即 a 的下标比 b 小。
整个过程就完成了一次升序的排列。
当然还有一个需要注意的情况,就是比较函数不传的时候,是如何进行排序的?
答案是将数字转换为字符串,然后根据字母unicode值进行升序排序,也就是根据字符串的比较规则进行升序排序。
IEEE754
将一个二进制转换为合适为:V=(-1)s次方 M2 E次方 来进行浮点数表示 S决定正还是负 M二进制小数,范围12-e次方或者01-e次方