前端回答(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在当期那窗口打开这个链接

浙公网安备 33010602011771号