带大家好好梳理下前端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的不同应用场景,如何取值?
- 手写bind函数
- 实际开发中闭包的应用场景,举例说明
- 创建10个标签,点击的时候弹出来对应的序号
知识点
- 作用域和自由变量
- 闭包
- 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)
})
}
}