前端回答(2)

1.JS的垃圾回收机制 

 

 

2.js几种数据类型

bigint,symbol,string,number,boolean,null,undefined,object

bigint与symbol是es6引入的新特性

bigint是为了解决number的范围(-2^53 + 1 ~ 2^53 - 1)有限制的问题

Symbol表示这个值是唯一的,与其他的都不相等,symbol可以解决命名冲突的问题。

说说Symbol.for

如果使用了symbol.for这个方法,就会被放在全局环境中来搜索。会先判断是否之前声明过这个名字的变量,先去找,如果找到相同的就返回,如果没有声明过就重新创建一个

1 let a = Symbol('lk')
2 let b = Symbol.for('lk')
3 let c = Symbol.for('lk')
4 console.log(a === b)   // false
5 console.log(b === c)   // true

 

3. class基本语法及继承 

先说说继承的几种方式

1.借用构造函数  

这种方式都严格意义上都不算继承,复用性差

Student只是单纯的Person的执行,并没有将Student和Person放到一个原型链上  

1 function Person() {xxx}
2 function Student() { 
3     Person.call(this)
4 }

2.原型链式继承

这种修改原型链的方式

但是这种方式的所有子类共享父类方法,各个子类之间对父类方法的修改,相互影响

1 function Person() {xxx}
2 function Student() {}
3 Student.prototype = new Person()
4 Student.prototype.constructor = Student

3.组合式继承

借用构造函数和原型链的方式相结合

这种方式看起来很美好,但是不可避免的是,对父类构造函数引用了两次

1 function Person(){xxx}
2 function Student() {
3   Person.call(this)  
4 }
5 Studnet.prototype = new Person()
6 Student.prototype.contruector = Student

4.寄生组合式继承

在这种继承方式中,用的还是组合式继承的方式,只是在修改原型链的时候使用的是父类的副本(在这里不一定是父类,副本就可以了)

1 function Person(){xxx}
2 function Student() {
3   Person.call(this)  
4 }
5 var per = Object.create(Person)
6 Student.prototype = per
7 Student.protorype.constructor = Student

 class

    

 

 

4.new和Object.create的区别 

new是用构造函数创建一个实例

new的原理是1.将这个新产生的对象,放到构造函数原型链上

      2.构造函数的执行

      3.如果构造函数执行返回的是对象,就把这个对象作为返回值,如果不是,就把新创建的这个对象作为返回值

new的原理

1 function myNew(Person){
2   var obj = {}
3   obj.__proto__ = Person.prototype4   var result = Person.call(this)    
5   return typeof result == 'object'? result : obj
6 }

Object.create(o)       以o为原型创建对象

原理与原型链继承的方式类似都是都是把对象添加到原型链上

Object.create(o)原理

1 function obj(o) {
2   function F(){}
3   F.prototype = o
4   return new F()    
5 }

 

5.箭头函数及其this问题 

箭头函数与一般函数的区别:

首先是写法上的区别,箭头函数的写法更简单

其次是this的问题,箭头函数是没有this的,他的this是继承自他所在的作用域的this

(举个栗子:setTimeout中的this一般是指向window的,但是我们可以在第一个函数的时候使用箭头函数,可以通过这种方式来修改this的指向)

箭头函数的this指向可以通过修改其所在作用域的this指向来修改他的指向

关于this指向的问题。

js是一个执行时语言,this的指向并不是在创建的时候就决定好了的,而是在执行时决定好的。this的指向是由调用者决定的,谁调用就指向谁。

 

6. Array.sort()方法与实现机制

是array的排序方法,是会修改原数组。接收一个比较函数作为参数,数组的每个元素就会按照比较函数的规则来比较

如果不传递参数就会按照ASCAII来比较,12 < 3

排序的原理:

在v8中,当数组的长度小于10,采用的是插入排序的方式,当数组长度大于10时,采用快速排序的方式。

 

7.Set和Map数据结构 

set和Map是es6新引入的数据结构

set是集合,集合特点:里面的元素都不重复(对象相等的验证不言而喻)

所以可以用set来对数组去重

map是和object类似的hash结构,区别是object的键名只能是字符串,但是map的键名可以是任意值,用map来表示hash更接近

关于WeakSet和WeakMap

WeakSet中的值只能是对象,WeakMap中的键名只能是对象

但是这些对象的引用都是弱引用,对于垃圾回收机制来说完全不考虑他们对对象的引用,如果这个对象的引用为0时就直接回收,不考虑他们对对象的引用。

通过这种方式可以减少内存泄露,但是不能用这个来存值,因为它的存在是由垃圾回收的运行决定的。

但是可以把DOM节点作为键名,通过WeakMap,来添加事件。

这样当DOM对象消失,他绑定的监听函数也会消失,就不会造成内存泄露

 

8.Proxy (待优化)

对象拦截,代理

在vue3.0中就使用Proxy来替代Object.defineProperty

在vue2.0中使用Object.defineProperty来重写对象属性的get和set

Proxy比Object.defineProperty的优点:

1.首先defineProperty是直接对对象的修改,这样代价很大。Proxy是通过创建一个对象副本来修改

2.defineProperty对新增的数据和数组的一些方法不能很好的监听。

 

9.CSS权重及其引入方式 

css的引入方式:通过内联的方式<link src="xxx">

        可以通过直接内嵌,写在<style></style>中(一般都在head中)

        直接写在行内的方式 <div style="color:red">

这三种方式权重由高到低

再说说选择器的权重

!important   infinity
行间样式 1000
#id 100
.class/:伪类/[属性] 10
标签/::伪元素 1
通配符 0

10. <a></a>标签全部作用

a标签设置link,visited,hover,active设置的顺序

a标签上的属性herf是直接跳转的路径,作为超链接,或者锚点

_blank在一个新的空窗口打开这个链接

_self在当期那窗口打开这个链接

posted @ 2020-10-07 22:09  kkkllo  阅读(174)  评论(0)    收藏  举报