前端面试题整理(带答案--不定期更新)

1、写出下面代码打印结果:

function Foo() {
    Foo.a = function() {
        console.log(1)
    }
    this.a = function() {
        console.log(2)
    }
}
// 以上只是 Foo 的构建方法,没有产生实例,此刻也没有执行

Foo.prototype.a = function() {
    console.log(3)
}
// 现在在 Foo 上挂载了原型方法 a ,方法输出值为 3

Foo.a = function() {
    console.log(4)
}
// 现在在 Foo 上挂载了直接方法 a ,输出值为 4

Foo.a();
// 立刻执行了 Foo 上的 a 方法,也就是刚刚定义的,所以
// # 输出 4

let obj = new Foo();
/* 这里调用了 Foo 的构建方法。Foo 的构建方法主要做了两件事:
1. 将全局的 Foo 上的直接方法 a 替换为一个输出 1 的方法。
2. 在新对象上挂载直接方法 a ,输出值为 2。
*/

obj.a();
// 因为有直接方法 a ,不需要去访问原型链,所以使用的是构建方法里所定义的 this.a,
// # 输出 2

Foo.a();
// 构建方法里已经替换了全局 Foo 上的 a 方法,所以
// # 输出 1


//打印结果
//4
//2
//1

2、写出下面代码打印结果:

function changeObjProperty(o) {
  o.siteUrl = "http://www.baidu.com"
  o = new Object()
  o.siteUrl = "http://www.google.com"
} 
let webSite = new Object();
changeObjProperty(webSite);
console.log(webSite.siteUrl);


//打印结果
//http://www.baidu.com

执行函数changeObjProperty的时候是将webSite的引用传递给了函数的形参,也就是把webSite的引用地址复制给了o,函数里面第一行改变的是对应引用地址内的对象的属性值,也就是webSite的属性值,第二行将o指向了另一个新对象,函数里面第三行改变的是新对象的属性值,跟webSite无关,故打印结果为http://www.baidu.com;

可以对题目做如下改动,应该会更清晰:

function changeObjProperty(a) {
  a.siteUrl = "http://www.baidu.com"
  a = new Object()
  a.siteUrl = "http://www.google.com"
  a.age = 25
} 
var webSite = new Object();
webSite.age= 20
changeObjProperty(webSite);
console.log(webSite); // {age: 20, siteUrl: 'http://www.baidu.com'}

3、用 JavaScript 写一个函数,输入 int 型,返回整数逆序后的字符串。如:输入整型 1234,返回字符串“4321”。要求必须使用递归函数调用,不能用全局变量,输入函数必须只有一个参数传入,必须返回字符串。

注意审题,要求必须使用递归函数

其实不考虑后面的要求完成整型到字符串的翻转很简单

let intToString = value => (value + '').split('').reverse().join('')
intToString(12345)    //54321

但是要用递归

function fun(num){
    let num1 = num / 10;
    let num2 = num % 10;
    if(num1<1){
        return num;
    }else{
        num1 = Math.floor(num1)
        return `${num2}${fun(num1)}`
    }
}
var a = fun(12345)
console.log(a)
console.log(typeof a)

4、给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。要求:必须在原数组上操作,不能拷贝额外的数组;尽量减少操作次数。示例:输入:[0,1,0,3,12],输出: [1,3,12,0,0]

function zeroMove(array) {
   let len = array.length;
   let j = 0;
   for(let i=0;i<len-j;i++){
       if(array[i]===0){
           array.push(0);
           array.splice(i,1);
           i --;
           j ++;
       }
   }
   return array;
}

5、打印出1-10000之间所有的对称数

[...Array(10000).keys()].filter((x) => {
    return x.toString().length > 1 && x === Number(x.toString().split('').reverse().join(''))
})

6、Vue 的父组件和子组件生命周期钩子执行顺序是什么

  • 加载渲染过程:父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
  • 子组件更新过程:父beforeUpdate->子beforeUpdate->子updated->父updated

7、写出打印结果

var a={}, b='123', c=123;  
a[b]='b';
a[c]='c';  
console.log(a[b]);   //c
//其他类型的键名会被转换成字符串类型,所有'123'和123作为键名是一样的


var a={}, b=Symbol('123'), c=Symbol('123');  
a[b]='b';
a[c]='c';  
console.log(a[b]);  //b
//Smybol类型的值都是不相等的


var a={}, b={key:'123'}, c={key:'456'};  
a[b]='b';
a[c]='c';  
console.log(a[b]);  //c
//b和c两个对象调用toString方法后都被转换成字符串[object Object],所以两个键名是一样的

这题考察的是对象的键名的转换。

  • 对象的键名只能是字符串和 Symbol 类型。
  • 其他类型的键名会被转换成字符串类型。
  • 对象转字符串默认会调用 toString 方法。

8、介绍一下BFC、IFC、GFC 和 FFC

FC的全称是:Formatting Contexts,它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。

BFC(Block formatting contexts):块级格式上下文
页面上的一个隔离的渲染区域,那么他是如何产生的呢?可以触发BFC的元素有float、position、overflow、display:table-cell/ inline-block/table-caption ;BFC有什么作用呢?比如说实现多栏布局’

IFC(Inline formatting contexts):内联格式上下文
IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC中的line box一般左右都贴紧整个IFC,但是会因为float元素而扰乱。float元素会位于IFC与与line box之间,使得line box宽度缩短。 同个ifc下的多个line box高度会不同
IFC中时不可能有块级元素的,当插入块级元素时(如p中插入div)会产生两个匿名块与div分隔开,即产生两个IFC,每个IFC对外表现为块级元素,与div垂直排列。
那么IFC一般有什么用呢?
水平居中:当一个块要在环境中水平居中时,设置其为inline-block则会在外层产生IFC,通过text-align则可以使其水平居中。
垂直居中:创建一个IFC,用其中一个元素撑开父元素的高度,然后设置其vertical-align:middle,其他行内元素则可以在此父元素下垂直居中。

GFC(GrideLayout formatting contexts):网格布局格式化上下文
当为一个元素设置display值为grid的时候,此元素将会获得一个独立的渲染区域,我们可以通过在网格容器(grid container)上定义网格定义行(grid definition rows)和网格定义列(grid definition columns)属性各在网格项目(grid item)上定义网格行(grid row)和网格列(grid columns)为每一个网格项目(grid item)定义位置和空间。那么GFC有什么用呢,和table又有什么区别呢?首先同样是一个二维的表格,但GridLayout会有更加丰富的属性来控制行列,控制对齐以及更为精细的渲染语义和控制。

FFC(Flex formatting contexts):自适应格式上下文
display值为flex或者inline-flex的元素将会生成自适应容器(flex container),可惜这个牛逼的属性只有谷歌和火狐支持,不过在移动端也足够了,至少safari和chrome还是OK的,毕竟这俩在移动端才是王道。Flex Box 由伸缩容器和伸缩项目组成。通过设置元素的 display 属性为 flex 或 inline-flex 可以得到一个伸缩容器。设置为 flex 的容器被渲染为一个块级元素,而设置为 inline-flex 的容器则渲染为一个行内元素。伸缩容器中的每一个子元素都是一个伸缩项目。伸缩项目可以是任意数量的。伸缩容器外和伸缩项目内的一切元素都不受影响。简单地说,Flexbox 定义了伸缩容器内伸缩项目该如何布局。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章