1、var、let 及 const 区别


  • var 存在提升,可以在声明之前使用 值为 undefined。let、const 不可以是因为会形成暂时性死区
  • let 和 const 作用基本一致,前者不允许在同一个作用域重复声明同一个变量,后者声明一个基本类型的时候为常量,不可修改;声明对象可以修改

2、说一下内置类型

JS 中有其中内置类型,可以分为两大类型:基本类型(栈)和对象(堆)

基本类型有六种:null,undefined,boolean,number,string,symbol

对象( Object )是引用类型,在使用过程会涉及到浅拷贝和深拷贝的问题

typeof 对于基本类型,除了null 都可以正常显示

3、实现 instanceof 原理

instanceof 可以正确判断对象类型,判断方式以原型链的方式查找

function myInstanceof(left,right){
let prototype = right.prototype;
left = left.__proto__;
while(true){
if(left === null || left === undefined)
return false
if(prototype === left)
return true
left = left.__proto__
}
}

4、原型及原型链

每个函数都有自己的 prototype

每个对象都有 ​proto​属性,指向了创建该对象的构造函数的原型。其实这个属性指向了 prototype,所以使用 ​proto​ 来访问

对象可以通过​proto​ 来寻找不属于该对象的属性,​proto​ 将对象连接起来组成了原型链

5、this指向

改变this指向可以通过 call、apply、bind. 传参形式分别是 参数队列,数组,函数

箭头函数其实没有this,这个函数中的 this 只取决于他外面的第一个不是箭头函数的函数的 this

function foo() {
console.log(this.a)
}
var a = 1
foo()

var obj = {
a: 2,
foo: foo
}
obj.foo()

// 以上两者情况 `this` 只依赖于调用函数前的对象,优先级是第二个情况大于第一个情况

// 以下情况是优先级最高的,`this` 只会绑定在 `c` 上,不会被任何方式修改 `this` 指向
var c = new foo()
c.a = 3
console.log(c.a)

// 还有种就是利用 call,apply,bind 改变 this,这个优先级仅次于 new

6、new的原理


  • 生成一个新的对象
  • 链接到原型上
  • 绑定 this
  • 返回一个新的对象

// 实现 new 
function create(Con, ...args){
let obj = {} //生成新对象
obj.__proto__ = Con.prototype //链接原型
let res = Con.apply(obj,args)
return res instanceof Object ? res : obj //确保返回的是对象
}

7、闭包

闭包的定义很简单:函数 A 返回了一个函数 B,并且函数 B 中使用了函数 A 的变量,函数 B 就被称为闭包。

function A() {
let a = 1
function B() {
console.log(a)
}
return B
}

8、深浅拷贝

第一种可以通过 Object.assign来实现,第二种可以通过扩展运算符 ( ... )

let a = {
age:21
}
let b = Object.assign({},a) // 等同于 let b = {...a}
a.age = 18
console.log(b.age) // 1

深拷贝主要解决引用地址相同的问题

// 第一种可以通过 JSON.parse(JSON.stringify(object))
// 该方法有局限性 不能解决嵌套的引用对象
let a = {
age: 18,
name:{
first:'wysoka'
}
}
let b = JSON.parse(JSON.stringify(a))
a.name.first = 'web'
console.log(b.name.first) // wysoka

// 第二种方法 自定义方法
function deepcopy(obj){
let res = obj instanceof Array ? [] : {}
for(const [k,v] of Object.entries(obj)){
res[k] = typeof v = 'object' ? copy(v) : v
}
return res;
}

9、 防抖、节流

防抖:在一段时间内把最后一次的操作为准,在规定时间内,重复操作重新计时

// 通俗易懂版
function debounce(fn,time){
var t = null;
return function(){
clearTimeout(t);
t = setTimeout(fn,time);
}
}

节流:好比国企单位到点就下班,在规定的时间内,到时间就输出,在浏览器当中的刷新频率60HZ相当于起到节流的作用

// 通俗易懂版
function throttle(callback,duration){
var lasttime = 0;
return function(){
var now = new Date().getTime();
if(now - lasttime > 1000){
callback();
lasttime = now;
}
}
}

10、 事件触发分为三个阶段


  • 捕获阶段、处于目标阶段、冒泡阶段
  • 冒泡型事件:当你使用事件冒泡时,子级元素先触发,父级元素后触发 stopPropagation()
  • 捕获型事件:当你使用事件捕获时,父级元素先触发,子级元素后触发 preventDefault()
  • DOM事件流:同时支持两种事件模型:捕获型事件和冒泡型事件

原创作者:Wysoka

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。