# 2020 / 3 / 16

内容出自「牛客网」 入口:https://www.nowcoder.com/discuss/297026?type=post&order=time&pos=&page=1

# 1 / 继承方式都有几种?实现一个实例继承

  • 原型链继承
  • 构造函数继承
  • 实例继承
  • 拷贝继承
  • 组合继承
  • 寄生组合继承

实现一个实例继承

// 定义一个动物类
function Animal (name) {
  // 属性
  this.name = name || 'Animal';
  // 实例方法
  this.sleep = function(){
    console.log(this.name + '正在睡觉!');
  }
}
// 原型方法
Animal.prototype.eat = function(food) {
  console.log(this.name + '正在吃:' + food);
};


function Cat(name){
    var instance = new Animal()
    instance.name = name || 'Tom'
    return instance
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 2 / bind call apply 区别,bind有几个参数? 实现一个bind函数

call,apply都属于立即执行函数,它们的区别在于接收的参数不同,call是依次传入参数,而apply接受一个数组作为参数;而bind则是返回一个新的函数,它不会立即执行,它接受多个参数,第一个参数作为绑定的对象,其他参数作为执行参数。

手写一个bind

Function.prototype.myBind = function(Argument){
    if(typeof this !== 'function'){
        throw new TypeError('this should be a function')
    }

    const args = [].slice.call(arguments, 1) // 获取除第一个参数之外的参数
    const self = this // this 指向调用 myBind 的函数
    const 

    const savePrototype = function(){}

    const bind = function(){
        return self.apply(this instanceof savePrototype ? this : Argument, agrs.concat([].slice.call(arguments)))
    }

    if(this.prototype){
        savePrototype.prototype = this.prototype
    }

    bind.prototype = new savePrototype()
    return bind
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 3 / v-model原理?

v-model 本质上是 v-bind 和 v-on 的语法糖,用来在表单控件或组件上创建双向绑定 而vue实现双向绑定通过以下4个步骤:

  • 实现一个监听器(Observer):对数据对象进行遍历,包括子属性对象的属性,利用Object.defineProperty()在属性上劫持getter和setter,这样,当给对象的某个值进行某种操作时,都会触发setter,那么就可以监听到数据的变化
  • 实现一个解析器(Complie):解析Vue的模板指令,将模板中的变量转换为数据,然后初始化页面视图,并在每个指令对应的节点上都绑定更新函数,添加添加数据的订阅者,一旦数据发生变化,就会收到通知,调用绑定好的更新函数进行数据更新
  • 实现一个订阅者(Watcher):订阅者是监听器和解析器通信的桥梁,主要任务是订阅监听者中的属性值变化的消息,一旦收到属性值变化的消息后,就会通知解析器,解析器收到通知后触发更新函数
  • 实现一个订阅器(Dep):订阅器采用发布订阅的设计模式,用来收集订阅者,对监听器和订阅者进行统一管理

简单来说,Vue通过数据劫持配合发布订阅者的设计模式,内部通过Object.defineProperty()来劫持各个属性的getter和setter,在数据变化的时候通知订阅者,订阅者通知解析器,解析器收到通知后触发更新函数。

# 4 / margin塌陷是什么?解决方法?

当两个盒子在垂直方向上设置margin值时,会出现重叠现象, 解决方式:

  • 给父级设置边框或内边距(不建议)
  • 触发BFC(块级格式上下文),改变父级的渲染规则
    • position:absolute / fixed;
    • display:inline-block;
    • overflow:hidden;(不为visible)
    • float:left / right;(不为none)

# 5 / display的值有什么?

  • none:元素会被隐藏
  • inline:元素会被设置为内联元素
  • block:元素会被设置为块级元素
  • inline-block:元素会被设置为行内块级元素
  • list-item:元素会作为列表显示、
  • table:元素会作为块级表格来显示(类似table),表格前后带有换行符
  • flex:元素会进入flex布局模式

# 6 / css 长度单位都有哪些? em,rem ,px区别?

  • px:固定长度单位,一旦设置就不会因为适应页面大小而改变
  • em:相对于父元素的字体大小的单位
  • rem:相对于根元素的字体大小的单位
  • rpx:小程序单位
  • vh:当前窗口高度的百分比
  • vw:当前串口宽度的百分比

# 7 / 重排和重绘都是什么?

  • 重绘:当一个元素自身的宽高,布局,以及显示或隐藏没有改变,而只是改变了元素外观风格时,则引起重绘
  • 重排:当渲染树的一部分或全部元素因改变了自身的宽高,布局,显示和隐藏,或元素内部的文字结构发生变化,导致需要重新构建页面的时候,就产生重排