前端面试题整理三

1、继承的几种方式及优缺点?
  • 原型链继承
function Parent () {
    this.name = 'kevin';
}

Parent.prototype.getName = function () {
    console.log(this.name);
}

function Child () {

}

Child.prototype = new Parent();

var child1 = new Child();

console.log(child1.getName()) // kevin

缺点:1.引用类型的属性被所有实例共享
2.在创建 Child 的实例时,不能向Parent传参

  • 借用构造函数(经典继承)
function Parent () {
    this.names = ['kevin', 'daisy'];
}

function Child () {
    Parent.call(this);
}

var child1 = new Child();

child1.names.push('yayu');

console.log(child1.names); // ["kevin", "daisy", "yayu"]

var child2 = new Child();

console.log(child2.names); // ["kevin", "daisy"]

优点:1.避免了引用类型的属性被所有实例共享
2.可以在 Child 中向 Parent 传参
缺点:方法都在构造函数中定义,每次创建实例都会创建一遍方法。

  • 组合继承
function Parent (name) {
    this.name = name;
    this.colors = ['red', 'blue', 'green'];
}

Parent.prototype.getName = function () {
    console.log(this.name)
}

function Child (name, age) {

    Parent.call(this, name);
    
    this.age = age;

}

Child.prototype = new Parent();

var child1 = new Child('kevin', '18');

child1.colors.push('black');

console.log(child1.name); // kevin
console.log(child1.age); // 18
console.log(child1.colors); // ["red", "blue", "green", "black"]

var child2 = new Child('daisy', '20');

console.log(child2.name); // daisy
console.log(child2.age); // 20
console.log(child2.colors); // ["red", "blue", "green"]

优点:融合原型链继承和构造函数的优点,是 JavaScript 中最常用的继承模式。

  • 原型式继承
function createObj(o) {
    function F(){}
    F.prototype = o;
    return new F();
}

就是 ES5 Object.create 的模拟实现,将传入的对象作为创建的对象的原型。
缺点:包含引用类型的属性值始终都会共享相应的值,这点跟原型链继承一样。

2、HTML5新增标签和使用

语义化的好处

  • 代码结构: 使页面没有css的情况下,也能够呈现出很好的内容结构
  • 有利于SEO: 爬虫依赖标签来确定关键字的权重,因此可以和搜索引擎建立良好的沟通,帮助爬虫抓取更多的有效信息
  • 提升用户体验: 例如title、alt可以用于解释名称或者解释图片信息,以及label标签的灵活运用。
  • 便于团队开发和维护: 语义化使得代码更具有可读性,让其他开发人员更加理解你的html结构,减少差异化。
  • 方便其他设备解析: 如屏幕阅读器、盲人阅读器、移动设备等,以有意义的方式来渲染网页。

布局相关的常用标签

定义一个页面或是区域的头部
定义一个区域
定义一个页面或是区域的底部
3、内存泄露

定义:应用程序不再需要占用内存的时候,由于某些原因,内存没有被操作系统或可用内存池回收
常见内存泄露的原因

  • 意外的全局变量
  • 被遗忘的计时器或回调函数
  • 脱离 DOM 的引用
  • 闭包
4、ES6Object新增方法
  • Object.is()
    传入两个要比较的值,判断是否相同,全等的话返回true,不全等返回false。
  • Object.assign()
    Object.assign()方法用于对象的合并,将源对象( source )的所有可枚举属性,复制到目标对象( target )。
    注意:这里是浅拷贝!!
    如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性!!
  • Object.keys()、Object.values()、Object.entries()
    Object.keys()方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历( enumerable )属性的键名数组。
    Object.values()方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历( enumerable )属性的键值数组。
    Object.entries()方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历( enumerable )属性的键值对数组。
let obj = {name:"winne",age:22};
let objKeys = Object.keys(obj);
let objValues = Object.values(obj);
let objItem = Object.entries(obj);

console.log(objKeys);   //["name","age"]
console.log(objValues); //["winne",22]
console.log(objItem);   //[["name","winne"],["age",22]]
5、ES6数组的map方法
  • 应用场景1
    假定有一个数值数组,将数组中的值以双倍的形式放到另一个数组中
 var arr = [1,2,3,4,5]
        var doubleNumber = arr.map(function(num){
            return num*2
        })    
     console.log(doubleNumber) //[2,4,6,8,10] 
  • 应用场景2
    假定有一个对象数组,将数组中对象的某个属性的值存储到B数组中
var arr = [
            {
                name:'Jack',age:'16',sex:'男'     
            },{
                name:'Jerry',age:'18',sex:'男'    
            },{
                name:'Bailey',age:'14',sex:'女'    
            }
        ]
 var names = arr.map(function(name){
            return name.name;
        })
 console.log(names) //  ["Jack", "Jerry", "Bailey"]
6、ES6新增数组方法
  • 新增数组创建方法
    1、Array.from
    Array.from的设计目的是快速便捷把一个类似数组的可迭代对象创建成一个新的数组实例。
    通俗的讲,只要一个对象有length,Array.from就能把它变成一个数组,返回新的数组,而不改变原对象。
// String
Array.from('abc'); // ["a", "b", "c"]
// Set
Array.from(new Set(['abc', 'def'])); // ["abc", "def"]
// Map
Array.from(new Map([[1, 'abc'], [2, 'def']])); // [[1, 'abc'], [2, 'def']]

2、Array.of

Array.of() // []
Array.of(undefined) // [undefined]
Array.of(3) // [3]
Array.of(3, 4, 5) // [3, 4, 5]
  • 新增数组修改方法
    1、copyWithin
['a','b','c','d','e','f','g'].copyWithin(0, 3) //  ["d", "e", "f", "g", "e", "f", "g"]
['a','b','c','d','e','f','g'].copyWithin(0, 3, 4) //  ["d", "b", "c", "d", "e", "f", "g"]

2、fill
使用给定值,填充一个数组。

[1,2,3,4,5].fill('a');
// ["a", "a", "a", "a", "a"]

new Array(3).fill(12)
// [12, 12, 12]
  • 新增数组查找遍历方法
    1、find 和 findIndex
    find 返回数组中第一个满足条件的元素(如果有的话), 如果没有,则返回undefined。
    数组实例的 findIndex 方法的用法与 find 方法很类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回 -1。
    2、includes
    方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的 includes 方法类似。
    includes 第二个参数表示搜索的起始位置:
['a','b','c','d'].includes('c',2)  //true
['a','b','c','d'].includes('c',3)  //false

3、entries、keys、values
用法类似对象

  • 降维方法
    1、flat
    flat用于将嵌套的数组“拉平”。该方法返回一个新数组,对原数据没有影响。
[1, 2, [3, 4]].flat()
// [1, 2, 3, 4]

2、flatMap
方法对原数组的每个成员执行一个函数(相当于执行 Array.prototype.map),然后对返回值组成的数组执行 flat() 方法。该方法返回一个新数组,不改变原数组。

[2, 3, 4].flatMap((x) => [x, x * 2])
// [2, 4, 3, 6, 4, 8]
// 相当于 [[2, 4], [3, 6], [4, 8]].flat()

你可能感兴趣的:(前端面试题整理三)