常用的js知识点

60 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情

一些常常用到的js知识点,总结一下,温故而知新!

闭包🐶

产生闭包的背景

  • 全局变量很容易被污染,为了减少全局变量的使用,将参数定义在函数体内
  • 函数体内的参数,外界无法使用,所以在函数内返回一个新的函数,并将参数放在其中供外部调用

闭包的概念

  • 闭包就是一个函数内部的函数
  • 解决的问题:使外部可以调用函数内部的变量
  • 问题:闭包会导致变量不会被GC回收,所以不要滥用闭包

举个栗子

for(var i = 0;i <= 5; i++){
    setTimeout(function fun() {
        console.log(i)
    },i*1000)
}

打印结果是:666666.而我想打印012345就需要修改为

for(let i = 0;i <= 5; i++){
    (function () {
        setTimeout(function fun() {
            console.log(i)
        },i*1000)
    })(i)
}

柯里化🐶

  • 柯里化可以让我们给一个函数传递较少的参数,得到一个已经记住了某些固定参数的新函数
  • 通过闭包,对函数参数进行缓存
  • 让函数变得更灵活,让函数的粒度更小
  • 可以把多元函数转换成一元函数,可以组合使用函数产生强大的功能

举个栗子

可以实现如下效果

// add(1)(2)(3) = 6;
// add(1, 2, 3)(4) = 10;
// add(1)(2)(3)(4)(5) = 15;
var add_currying = function(...rest){
    var sum = 0;
    for(let item of rest){
        sum += item;
    }
    var add_back = (...rest) => {
        for(let item of rest){
            sum += item;
        }
        return add_back;
    };
    add_back.toString = () => sum;
    return add_back;
}

浅拷贝和深拷贝🐶

  • 基本数据类型:名字和值都存在栈中
  • 引用数据类型:名字在栈中,值在堆中,栈内存会提供一个引用地址,指向堆内存中的值
  • 浅拷贝:1.for只遍历第一层 2.assign 3. =直接赋值
  • 深拷贝:1.递归遍历所有层级 2.利用JSON对象【JSON.stringfy() JSON.parse()】 3.通过jQuery的extend方法实现深拷贝 4.lodash函数库实现深拷贝 5.用slice实现对数组的深拷贝,slice() 方法可从已有的数组中返回选定的元素。6.使用扩展运算符实现深拷贝 8.Reflect法 9.用concat实现对数组的深拷贝 10.直接使用var newObj = Object.create(oldObj),可以达到深拷贝的效果。11.手动实现深拷贝 7.如对象的value是基本类型,可以用Object.assign来实现深拷贝,但是要把它赋值给一个空对象
  • assign第一层是深拷贝,第二层以后是浅拷贝

举个栗子

function deepClone2(obj) {
  var _obj = JSON.stringify(obj),
    objClone = JSON.parse(_obj);
  return objClone;
} // 无法实现对对象中方法的深拷贝,会显示为undefined
var array = [1,2,3,4];
var newArray = $.extend(true,[],array); // true为深拷贝,false为浅拷贝
let result = _.cloneDeep(test)

this指向

  • 一般函数,this指向全局对象window;
  • 在严格模式下"use strict",为undefined.
  • 对象的方法里调用,this指向调用该方法的对象. 【this指的是,调用函数的那个对象】
  • 构造函数里的this,指向创建出来的实例.

用??代替||

||运算符是左边是空字符串或false0falsy值,都会返回后侧的值。而??必须运算符左侧的值为nullundefined时,才会返回右侧的值。因此0||1的结果为1,0??1的结果为0

使用?.简化&&和三元运算符

?.直接在链式调用的时候判断,判断左侧的对象是否为nullundefined,如果是的,就不再往下运算,返回undefined,如果不是,则返回右侧的值

使用Array.prototype.at()简化arr.length

Array.prototype.at()接收一个正整数或者负整数作为参数,表示获取指定位置的成员 参数正数就表示顺数第几个,负数表示倒数第几个,这可以很方便的某个数组末尾的元素

举个栗子

var arr = [12345] // 以前获取最后一位 console.log(arr[arr.length-1]) //5 // 简化后 console.log(arr.at(-1)) // 5

使用模板字符串代替原始的字符串拼接

//Longhand console.log('You got a missed call from ' + number + ' at ' + time); //Shorthand console.log(`You got a missed call from ${number} at ${time}`);