前端:js知识体系的建立和面试点梳理(一)

694 阅读4分钟

带大家好好梳理下前端js的基础知识

话不多说先上思维导图来看看知识体系的总览

一.JS基本知识

1.变量类型和计算

常见题目:

  • typeof能判断哪些类型?
  • 何时使用===何时使用==?
  • 值类型和引用类型的区别?
  • 手写深拷贝

知识点:

  • 变量类型

  • 值类型vs引用类型

  • typeof运算符

  • 深拷贝

  • 变量计算

值类型:

let a = 100;
let b = a;
a = 200;
console.log(b) //100

引用类型:

let a = {age: 20};
let b = a;
b.age = 21; 
console.log(a.age) //21

深入分析:

值类型的存储

引用类型的存储

常见值类型:

let a //undefined 注意const必须是有赋值的
const s = 'abc'
const n = 100
const b = true
const s = Symbol('s')

常见引用类型:

const obj = {x:100} //object
const arr = {'a','b'} //array
const n = null //指向空地址
function fn(){}

typeof 运算符

作用:

  • 识别所有值类型

  • 识别函数

  • 识别引用类型

    //判断值类型 let a //undefined const s = 'abc' // string const n = 100 //number const b = true //boolean const s = Symbol('s') //symbol

    //判断函数 typeof console.log //function typeof function(){} //function //识别引用类型 typeof null // object typeof ['a','b'] //object typeof {x:100} //object

深拷贝

重新开辟空间

//手撕深拷贝
function deepClone(obj = {}){
    if(typeof obj !== 'object'|| obj == null){
        return obj;//不是数组或者对象,直接返回
    }
    //初始化结果
    let result;
    if(obj instanceof Array){
        result = [];
    }  else {
        result = {};
    }
    for (let key in obj){
        //保证key不是原型属性
        if (obj.hasOwnProperty(key)){
            //递归调用
            result[key] = deepClone(obj[key])
        }    
    }
    return result;
}

变量计算

字符串拼接

const a = 100 + 10 //110
const b = 100 + '10' //'10010'

==运算符

100 == '100' //true
0 == ' ' //true
0 == false //true
null == undefined //true

//除了 ==null 之外,一律用===
const obj = {x:100}
if(obj.a == null){}//相当于if (obj.a === null||obj.a === undefined){}

if 语句和逻辑运算

truly变量:!!a === true

falsely变量:!!b === false

//除以下变量,全是truely变量
!!0 === false
!!NAN === false
!!'' === false
!!null === false
!!undefined === false
!!false === false

注意if语句判断的是truly变量,falsely变量

console.log(10&&0) //0
console.log(''||'abc') //'abc'
console.log(!window.abc) //true

2.原型和原型链

常见题目:

  • 如何准确判断一个变量是不是数组?
  • 手写一个建议的jQuery,考虑插件和扩展性
  • class的原型本质,怎么理解?

知识点:

  • class和继承
  • 类型判断instanceof
  • 原型和原型链

** class**

  • constructor

  • 属性

  • 方法

    class Student{ constructor(name,number){ this.name = name; this.number = number; this.gender = 'male'; } sayHi(){ console.log('姓名${this.name}') } } //通过类new对象/实例 const xialuo = new Student('xialuo',100) console.log(xialuo.name); xiaming.sayHi;

继承

  • extend

  • super

  • 拓展或者重写方法

    class People{ constructor(name){ this.name = name; } eat(){ console.log('{this.name} eat something') } } class Student extends People{ constructor (name,number){ super(name) this.number = number } sayHi(){ console.log('姓名{this.name} 学号${this.name}'); } }

类型判断- instanceof

xiaoming instanceof Student //true
xiaoming instanceof People //true
xiaoming instanceof Object //true

[] instanceof Array //true
[] instanceof Object //true

{} instanceof Object //true

原型

typeof People //'function'说明class只是语法糖
typeof Student //'function

//隐式原型和显示原型
console.log(xialuo.__proto__) //隐式原型
console.log(Student.prototype) //显示原型
console.log(xialuo.__proto__ === Student.prototype)

原型关系

  • 每个class都有显示原型prototype
  • 每个实例都有隐式原型_proto_
  • 实例的__proto__指向对应class的prototype

基于原型的执行规则

  • 获取属性xialuo.name或执行方法xialuo.sayHi()时
  • 先在自身属性和方法寻找
  • 如果找不到则自动去__proto__中查找

原型链

console.log(Student.prototype.__proto__)
console.log(People.prototype)
console.log(Student.prototype.__proto__ === People.prototype)

如何验证某个属性和方法是不是实例自身存在的:hasOwnProperty

instanceof顺着隐式原型往上查询。

3.作用域和闭包

常见题目:

知识点

  • 作用域和自由变量
  • 闭包
  • this

作用域:

变量的合法使用范围

  • 全局作用域
  • 函数作用域
  • 块级作用域

自由变量

  • 一个变量在当前作用域没有被定义,但是被使用了
  • 向上级作用域,一层一层一次寻找,直到找到为止
  • 如果到全局作用域都没有找到,则报错XX is not defined

闭包

  • 作用域应用的特殊情况,有两种表现:

  • 函数作为参数被传递

  • 函数作为返回值被返回

    //函数作为返回值 function create(){ const a = 100 return function(){ console.log(a) } }

    const fn = create() const a = 200 fn() //100

    //函数作为参数 function print(fn){ const a = 200 fn() } const a = 100 function fn(){ console.log(a); } print(fn) //100

!!!闭包:自由变量的查找,是在函数定义的地方,向上级作用域查找不是在执行的地方查找。

this

  • 作为普通函数去调用
  • 使用call apply bind
  • 作为对象方法被调用
  • 在class方法中调用
  • 箭头函数

(this取值在函数执行的时候确定的)

function fn1(){
    console.log(this)
}
fn1() //window
fn1.call({x:100}) //{x:100}
const fn2 = fn1.bind({x:200})
fn2() //{x:200} 

const zhangsan = {
    name:'张三',
    sayHi(){
        //this即当前对象
        console.log(this)
    },
    wait(){
        setTimeout(function(){
            //this === window
            console.log(this)
        })    
    }
}

const zhangsan = {
    name:'张三',
    sayHi(){
        //this即当前对象
        console.log(this)
    },
    wait(){
        setTimeout(()=>{
            //this 即当前对象
            console.log(this)
        })    
    }
}