前端基础知识汇总

183 阅读4分钟

前言:希望可以通过这篇文章,能够给你得到帮助。(感谢一键三连),前端小白不断升级打怪中...

1. es6和es5函数参数和arguments的差别

注: 这里说的 es5 代表的都是非严格模式下

es6之前函数的参数不能传默认值:

function fn(a, b){
    console.log(a)
    console.log(b)
}
fn(2)
// 2
// undefined

如果调用函数的时候传不传入对应的参数,则参数的值为 undefined

es6中查参数可以设置默认值,且默认值可以是任何类型(变量,数字、函数等)。

默认值为数字、字符串等非函数和变量:

function fn(a, b=3){
    console.log(a)
    console.log(b)
}

fn(2)
// 2
// 3

默认值为变量:

let d = 5;
function fn(a, b=a, c=d){
    console.log(a)
    cosnole.log(b)
    cosnole.log(c)
}
fn(2)
// 2
// 2
// 5

注意:默认值是变量且变量也是当前函数的参数的话,不能将后面的变量赋值给前面的参数当默认值,如上面代码,能将参数 a 赋值给 b ,但是不能将 b 赋值给 a 。

默认值为函数:

function testfn(){
    return 'test'
}
function fn(a, b=testfn()){
    console.log(a)
    console.log(b)
}
fn(2)
// 2
// test

注意,默认值如果是函数的话,只有在调用 fn 函数,且未传值的时候,才会调用。

es6和es5函数 arguments 的差别:

arguments 是函数传入的实参,在es6中,如果函数有设置默认值,那么修改参数变量的值,不会影响 arguments 里面值,如:

function fn(a, b=5){
    a = 3;
    console.log(a)
    console.log(arguments[0])
}
fn(2)
// 3
// 2

这里,我在函数内部将参数 a 的值改成了 3,但是arguments[0] 的值还是传入的2

如果定义函数的时候,没有设置默认值,那么修改参数的值会导致 arguments 里面的值同步被修改,如:

function fn(a, b){
    a = 3;
    console.log(a)
    console.log(arguments[0])
}
fn(2)
// 3
// 3

2. 实现sum(1,2) => 3, sum(1,2,3,4) => 10

function sum(arr) {
    return arr.reduce((preValue, curValue) => {
    	return preValue + curValue
    })
}
console.log(sum([0,1,2,3,4]))    // 10

3. reduce高级用法

let arr2 = arr.reduce((preValue,curValue)=>preValue + curValue,5)
console.log(arr2)    // 15


let arr = [0,1,2,3,4]
let arr2 = arr.reduce((preValue,curValue) => {
    return preValue + curValue
}, 5)
console.log(arr2)    // 15

计算数组中每个元素出现的次数

function times(arr) {
	return arr.reduce((pre, cur) => {
		if (cur in pre) {
			pre[cur]++
		} else {
			pre[cur] = 1
		}
		return pre
	}, {})
}
times(['peter', 'tom', 'mary', 'bob', 'tom','peter'])
// {peter: 2, tom: 2, mary: 1, bob: 1}

数组去重

let arr = [1,2,3,4,4,1]
let newArr = arr.reduce((pre,cur)=>{
    if(!pre.includes(cur)){
      return pre.concat(cur)
    }else{
      return pre
    }
},[])
console.log(newArr);// [1, 2, 3, 4]

将多维数组转化为一维

let arr = [[0, 1], [2, 3], [4,[5,6,7]]]
const newArr = function(arr){
   return arr.reduce((pre,cur)=>pre.concat(Array.isArray(cur)?          newArr(cur):cur),[])
}
console.log(newArr(arr)); //[0, 1, 2, 3, 4, 5, 6, 7]

4. === 与 == null与undefined

=== 比较两个操作数的值是否相等,同时检测它们的类型是否相同

== 比较两个操作数的值是否相等

NaN与任何值都不相等,包括它自己

null 和 undefined 值相等,但是它们是不同类型的数据。

对于复合型对象,主要比较引用的地址,不比较对象的值

null === undefined // false
null == undefined // true

// 两个对象的值相等,但是引用地址不同,所以它们既不想等,也不全等
var a = new String("abcd");  //定义字符串“abcd”对象
var b = new String("abcd");  //定义字符串“abcd”对象
console.log(a === b);  //返回false
console.log(a == b);  //返回false

5. bind apply call

相同点:

  • 都是用来改变函数的this对象的指向的。
  • 第一个参数都是this要指向的对象。
  • 都可以利用后续参数传参

区别:

  • bind 返回一个函数 第一个参数是改变this指向的对象 直接传参

  • apply 对函数的直接调用 第一个参数是改变this指向的对象 参数用数组包裹

  • call 对函数直接调用 第一个参数是改变this指向的对象 直接传参

  • cal和apply是直接调用函数

  • bind是返回函数本身,如果要执行,必须再后面再加()调用

www.cnblogs.com/echolun/p/1…

手写实现bind方法

Function.prototype.bind_ = function (obj) {
    //第0位是this,所以得从第一位开始裁剪
    var args = Array.prototype.slice.call(arguments, 1);
    var fn = this;
    return function () {
        //二次调用我们也抓取arguments对象
        var params = Array.prototype.slice.call(arguments);
        //注意concat的顺序
        fn.apply(obj, args.concat(params));
    };
};

var obj = {
    z: 1
};

function fn(x, y) {
    console.log(x + y + this.z);
};

var bound = fn.bind_(obj, 1);
bound(2); //4