前端经典面试题(60道前端面试题包含JS、CSS(1)

GIF:

  1. 8 位像素,256 色

  2. 无损压缩

  3. 支持简单动画

  4. 支持 boolean 透明

  5. 适合简单动画

JPEG

  1. 颜色限于 256

  2. 有损压缩

  3. 可控制压缩质量

  4. 不支持透明

  5. 适合照片

PNG

  1. 有 PNG8 和 truecolor PNG

  2. PNG8 类似 GIF 颜色上限为 256,文件小,支持 alpha 透明度,无动画

  3. 适合图标、背景、按钮

9、display,float,position 的关系

参考答案

  1. 如果display为 none,那么 position 和 float 都不起作用,这种情况下元素不产生框

  2. 否则,如果 position 值为 absolute 或者 fixed,框就是绝对定位的,float 的计算值为 none,display 根据下面的表格进行调整。

  3. 否则,如果 float 不是 none,框是浮动的,display 根据下表进行调整

  4. 否则,如果元素是根元素,display 根据下表进行调整

  5. 其他情况下 display 的值为指定值 总结起来:绝对定位、浮动、根元素都需要调整display

10、如何水平居中一个元素

参考答案

  • 如果需要居中的元素为常规流中 inline 元素,为父元素设置text-align: center;即可实现

  • 如果需要居中的元素为常规流中 block 元素,1)为元素设置宽度,2)设置左右 margin 为 auto。3)IE6 下需在父元素上设置text-align: center;,再给子元素恢复需要的值

aaaaaa aaaaaa a a a a a a a a

  • 如果需要居中的元素为浮动元素,1)为元素设置宽度,2)position: relative;,3)浮动方向偏移量(left 或者 right)设置为 50%,4)浮动方向上的 margin 设置为元素宽度一半乘以-1

aaaaaa aaaaaa a a a a a a a a

  • 如果需要居中的元素为绝对定位元素,1)为元素设置宽度,2)偏移量设置为 50%,3)偏移方向外边距设置为元素宽度一半乘以-1

aaaaaa aaaaaa a a a a a a a a

  • 如果需要居中的元素为绝对定位元素,1)为元素设置宽度,2)设置左右偏移量都为 0,3)设置左右外边距都为 auto

aaaaaa aaaaaa a a a a a a a a

JavaScript


1、JS有几种数据类型,其中基本数据类型有哪些?

参考答案

七种数据类型

  • Boolean

  • Null

  • Undefined

  • Number

  • String

  • Symbol (ECMAScript 6 新定义)

  • Object

(ES6之前)其中5种为基本类型:string,number,boolean,null,undefined,

ES6出来的Symbol也是原始数据类型 ,表示独一无二的值

Object为引用类型(范围挺大),也包括数组、函数,

2、Promise 构造函数是同步执行还是异步执行,那么 then 方法呢?

参考答案

const promise = new Promise((resolve, reject) => {

console.log(1)

resolve()

console.log(2)

})

promise.then(() => {

console.log(3)

})

console.log(4)

输出结果是:

1

2

4

3

promise构造函数是同步执行的,then方法是异步执行的

Promise new的时候会立即执行里面的代码 then是微任务 会在本次任务执行完的时候执行 setTimeout是宏任务 会在下次任务执行的时候执行

3、JS的四种设计模式

参考答案

工厂模式

简单的工厂模式可以理解为解决多个相似的问题;

function CreatePerson(name,age,sex) {

var obj = new Object();

obj.name = name;

obj.age = age;

obj.sex = sex;

obj.sayName = function(){

return this.name;

}

return obj;

}

var p1 = new CreatePerson(“longen”,‘28’,‘男’);

var p2 = new CreatePerson(“tugenhua”,‘27’,‘女’);

console.log(p1.name); // longen

console.log(p1.age);  // 28

console.log(p1.sex);  // 男

console.log(p1.sayName()); // longen

console.log(p2.name);  // tugenhua

console.log(p2.age);   // 27

console.log(p2.sex);   // 女

console.log(p2.sayName()); // tugenhua

单例模式

只能被实例化(构造函数给实例添加属性与方法)一次

// 单体模式

var Singleton = function(name){

this.name = name;

};

Singleton.prototype.getName = function(){

return this.name;

}

// 获取实例对象

var getInstance = (function() {

var instance = null;

return function(name) {

if(!instance) {//相当于一个一次性阀门,只能实例化一次

instance = new Singleton(name);

}

return instance;

}

})();

// 测试单体模式的实例,所以a===b

var a = getInstance(“aa”);

var b = getInstance(“bb”);

沙箱模式

将一些函数放到自执行函数里面,但要用闭包暴露接口,用变量接收暴露的接口,再调用里面的值,否则无法使用里面的值

let sandboxModel=(function(){

function sayName(){};

function sayAge(){};

return{

sayName:sayName,

sayAge:sayAge

}

})()

发布者订阅模式

就例如如我们关注了某一个公众号,然后他对应的有新的消息就会给你推送,

//发布者与订阅模式

var shoeObj = {}; // 定义发布者

shoeObj.list = []; // 缓存列表 存放订阅者回调函数

// 增加订阅者

shoeObj.listen = function(fn) {

shoeObj.list.push(fn); // 订阅消息添加到缓存列表

}

// 发布消息

shoeObj.trigger = function() {

for (var i = 0, fn; fn = this.list[i++]😉 {

fn.apply(this, arguments);//第一个参数只是改变fn的this,

}

}

// 小红订阅如下消息

shoeObj.listen(function(color, size) {

console.log(“颜色是:” + color);

console.log(“尺码是:” + size);

});

// 小花订阅如下消息

shoeObj.listen(function(color, size) {

console.log(“再次打印颜色是:” + color);

console.log(“再次打印尺码是:” + size);

});

shoeObj.trigger(“红色”, 40);

shoeObj.trigger(“黑色”, 42);

代码实现逻辑是用数组存贮订阅者, 发布者回调函数里面通知的方式是遍历订阅者数组,并将发布者内容传入订阅者数组

4、列举出集中创建实例的方法

参考答案

1.字面量

let obj={‘name’:‘张三’}

2.Object构造函数创建

let Obj=new Object()

Obj.name=‘张三’

3.使用工厂模式创建对象

function createPerson(name){

var o = new Object();

o.name = name;

};

return o;

}

var person1 = createPerson(‘张三’);

4.使用构造函数创建对象

function Person(name){

this.name = name;

}

var person1 = new Person(‘张三’);

5、简述一下前端事件流

参考答案

HTML中与javascript交互是通过事件驱动来实现的,例如鼠标点击事件onclick、页面的滚动事件onscroll等等,可以向文档或者文档中的元素添加事件侦听器来预订事件。想要知道这些事件是在什么时候进行调用的,就需要了解一下“事件流”的概念。

什么是事件流:事件流描述的是从页面中接收事件的顺序,DOM2级事件流包括下面几个阶段。

  • 事件捕获阶段

  • 处于目标阶段

  • 事件冒泡阶段

addEventListeneraddEventListener是DOM2 级事件新增的指定事件处理程序的操作,这个方法接收3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。

IE只支持事件冒泡

6、Function._proto_(getPrototypeOf)是什么?

参考答案

获取一个对象的原型,在chrome中可以通过__proto__的形式,或者在ES6中可以通过Object.getPrototypeOf的形式。

那么Function.proto是什么么?也就是说Function由什么对象继承而来,我们来做如下判别。

Function.proto==Object.prototype //false

Function.proto==Function.prototype//true

我们发现Function的原型也是Function。

我们用图可以来明确这个关系:

7、简述一下原型 / 构造函数 / 实例

参考答案

  • 原型(prototype): 一个简单的对象,用于实现对象的 属性继承。可以简单的理解成对象的爹。在 Firefox 和 Chrome 中,每个JavaScript对象中都包含一个__proto__(非标准)的属性指向它爹(该对象的原型),可obj.__proto__进行访问。

  • 构造函数: 可以通过new来 新建一个对象的函数。

  • 实例: 通过构造函数和new创建出来的对象,便是实例。实例通过__proto__指向原型,通过constructor指向构造函数

这里来举个栗子,以Object为例,我们常用的Object便是一个构造函数,因此我们可以通过它构建实例。

// 实例

const instance = new Object()

则此时, 实例为instance构造函数为Object,我们知道,构造函数拥有一个prototype的属性指向原型,因此原型为:

// 原型

const prototype = Object.prototype

这里我们可以来看出三者的关系:

实例.proto === 原型

原型.constructor === 构造函数

构造函数.prototype === 原型

// 这条线其实是是基于原型进行获取的,可以理解成一条基于原型的映射线

// 例如:

// const o = new Object()

// o.constructor === Object   --> true

// o.proto = null;

// o.constructor === Object   --> false

实例.constructor === 构造函数

8、简述一下JS继承,并举例

参考答案

在 JS 中,继承通常指的便是 原型链继承,也就是通过指定原型,并可以通过原型链继承原型上的属性或者方法。

  • 最优化: 圣杯模式

var inherit = (function(c,p){

var F = function(){};

return function(c,p){

F.prototype = p.prototype;

c.prototype = new F();

c.uber = p.prototype;

c.prototype.constructor = c;

}

})();

  • 使用 ES6 的语法糖 class / extends

9、函数柯里化

参考答案

在函数式编程中,函数是一等公民。那么函数柯里化是怎样的呢?

函数柯里化指的是将能够接收多个参数的函数转化为接收单一参数的函数,并且返回接收余下参数且返回结果的新函数的技术。

函数柯里化的主要作用和特点就是参数复用、提前返回和延迟执行。

在一个函数中,首先填充几个参数,然后再返回一个新的函数的技术,称为函数的柯里化。通常可用于在不侵入函数的前提下,为函数 预置通用参数,供多次重复调用。

const add = function add(x) {

return function (y) {

return x + y

}

}

const add1 = add(1)

add1(2) === 3

add1(20) === 21

10、说说bind、call、apply 区别?

参考答案

call 和 apply 都是为了解决改变 this 的指向。作用都是相同的,只是传参的方式不同。

除了第一个参数外,call 可以接收一个参数列表,apply 只接受一个参数数组。

let a = {

value: 1

}

function getValue(name, age) {

console.log(name)

console.log(age)

console.log(this.value)

}

getValue.call(a, ‘yck’, ‘24’)

getValue.apply(a, [‘yck’, ‘24’])

bind和其他两个方法作用也是一致的,只是该方法会返回一个函数。并且我们可以通过 bind实现柯里化。

(下面是对这三个方法的扩展介绍)

如何实现一个 bind 函数

对于实现以下几个函数,可以从几个方面思考

  • 不传入第一个参数,那么默认为 window

  • 改变了 this 指向,让新的对象可以执行该函数。那么思路是否可以变成给新的对象添加一个函数,然后在执行完以后删除?

Function.prototype.myBind = function (context) {

if (typeof this !== ‘function’) {

throw new TypeError(‘Error’)

}

var _this = this

var args = […arguments].slice(1)

// 返回一个函数

return function F() {

// 因为返回了一个函数,我们可以 new F(),所以需要判断

if (this instanceof F) {

return new _this(…args, …arguments)

}

return _this.apply(context, args.concat(…arguments))

}

}

如何实现一个call函数

Function.prototype.myCall = function (context) {

var context = context || window

// 给 context 添加一个属性

// getValue.call(a, ‘yck’, ‘24’) => a.fn = getValue

context.fn = this

// 将 context 后面的参数取出来

var args = […arguments].slice(1)

// getValue.call(a, ‘yck’, ‘24’) => a.fn(‘yck’, ‘24’)

var result = context.fn(…args)

// 删除 fn

delete context.fn

return result

}

如何实现一个apply函数

Function.prototype.myApply = function (context) {

var context = context || window

context.fn = this

var result

// 需要判断是否存储第二个参数

// 如果存在,就将第二个参数展开

if (arguments[1]) {

result = context.fn(…arguments[1])

} else {

result = context.fn()

}

delete context.fn

return result

}

11、箭头函数的特点

参考答案

function a() {

return () => {

return () => {

console.log(this)

}

}

}

console.log(a()()())

箭头函数其实是没有 this的,这个函数中的 this只取决于他外面的第一个不是箭头函数的函数的 this。在这个例子中,因为调用 a符合前面代码中的第一个情况,所以 this是 window。并且 this一旦绑定了上下文,就不会被任何代码改变。

程序阅读题


1、下面程序输出的结果是什么?

function sayHi() {

console.log(name);

console.log(age);

var name = “Lydia”;

let age = 21;

}

sayHi();

  • A: Lydia 和 undefined

  • B: Lydia 和 ReferenceError

  • C: ReferenceError 和 21

  • D: undefined 和 ReferenceError

参考答案

在函数中,我们首先使用var关键字声明了name变量。这意味着变量在创建阶段会被提升(JavaScript会在创建变量创建阶段为其分配内存空间),默认值为undefined,直到我们实际执行到使用该变量的行。我们还没有为name变量赋值,所以它仍然保持undefined的值。

使用let关键字(和const)声明的变量也会存在变量提升,但与var不同,初始化没有被提升。在我们声明(初始化)它们之前,它们是不可访问的。这被称为“暂时死区”。当我们在声明变量之前尝试访问变量时,JavaScript会抛出一个ReferenceError

关于let的是否存在变量提升,我们何以用下面的例子来验证:

let name = ‘ConardLi’

{

console.log(name) // Uncaught ReferenceError: name is not defined

let name = ‘code秘密花园’

}

let变量如果不存在变量提升,console.log(name)就会输出ConardLi,结果却抛出了ReferenceError,那么这很好的说明了,let也存在变量提升,但是它存在一个“暂时死区”,在变量未初始化或赋值前不允许访问。

变量的赋值可以分为三个阶段:

  • 创建变量,在内存中开辟空间

  • 初始化变量,将变量初始化为undefined

  • 真正赋值

关于letvarfunction

  • let的「创建」过程被提升了,但是初始化没有提升。

  • var的「创建」和「初始化」都被提升了。

  • function的「创建」「初始化」和「赋值」都被提升了。

2、下面代码输出什么

var a = 10;

(function () {

console.log(a)

a = 5

console.log(window.a)

var a = 20;

console.log(a)

})()

依次输出:undefined -> 10 -> 20

在立即执行函数中,var a = 20; 语句定义了一个局部变量 a,由于js的变量声明提升机制,局部变量a的声明会被提升至立即执行函数的函数体最上方,且由于这样的提升并不包括赋值,因此第一条打印语句会打印undefined,最后一条语句会打印20。

由于变量声明提升,a = 5; 这条语句执行时,局部的变量a已经声明,因此它产生的效果是对局部的变量a赋值,此时window.a 依旧是最开始赋值的10,

3、下面的输出结果是什么?

class Chameleon {

static colorChange(newColor) {

this.newColor = newColor;

}

constructor({ newColor = “green” } = {}) {

this.newColor = newColor;

}

}

const freddie = new Chameleon({ newColor: “purple” });

freddie.colorChange(“orange”);

  • A: orange

  • B: purple

  • C: green

  • D: TypeError

答案: D

colorChange方法是静态的。静态方法仅在创建它们的构造函数中存在,并且不能传递给任何子级。由于freddie是一个子级对象,函数不会传递,所以在freddie实例上不存在freddie方法:抛出TypeError

4、下面代码中什么时候会输出1?

var a = ?;

if(a == 1 && a == 2 && a == 3){

conso.log(1);

}

参考答案

因为==会进行隐式类型转换 所以我们重写toString方法就可以了

var a = {

i: 1,

toString() {

return a.i++;

}

}

if( a == 1 && a == 2 && a == 3 ) {

console.log(1);

}

5、下面的输出结果是什么?

var obj = {

‘2’: 3,

‘3’: 4,

‘length’: 2,

‘splice’: Array.prototype.splice,

‘push’: Array.prototype.push

}

obj.push(1)

obj.push(2)

console.log(obj)

参考答案

1.使用第一次push,obj对象的push方法设置 obj[2]=1;obj.length+=12.使用第二次push,obj对象的push方法设置 obj[3]=2;obj.length+=13.使用console.log输出的时候,因为obj具有 length 属性和 splice 方法,故将其作为数组进行打印 4.打印时因为数组未设置下标为 0 1 处的值,故打印为empty,主动 obj[0] 获取为 undefined

6、下面代码输出的结果是什么?

var a = {n: 1};

var b = a;

a.x = a = {n: 2};

console.log(a.x)

console.log(b.x)

参考答案

undefined {n:2}

首先,a和b同时引用了{n:2}对象,接着执行到a.x = a = {n:2}语句,尽管赋值是从右到左的没错,但是.的优先级比=要高,所以这里首先执行a.x,相当于为a(或者b)所指向的{n:1}对象新增了一个属性x,即此时对象将变为{n:1;x:undefined}。之后按正常情况,从右到左进行赋值,此时执行a ={n:2}的时候,a的引用改变,指向了新对象{n:2},而b依然指向的是旧对象。之后执行a.x = {n:2}的时候,并不会重新解析一遍a,而是沿用最初解析a.x时候的a,也即旧对象,故此时旧对象的x的值为{n:2},旧对象为 {n:1;x:{n:2}},它被b引用着。后面输出a.x的时候,又要解析a了,此时的a是指向新对象的a,而这个新对象是没有x属性的,故访问时输出undefined;而访问b.x的时候,将输出旧对象的x的值,即{n:2}。

7、下面代码的输出是什么?

function checkAge(data) {

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
img

学习笔记

主要内容包括html,css,html5,css3,JavaScript,正则表达式,函数,BOM,DOM,jQuery,AJAX,vue等等

HTML/CSS

**HTML:**HTML基本结构,标签属性,事件属性,文本标签,多媒体标签,列表 / 表格 / 表单标签,其他语义化标签,网页结构,模块划分

**CSS:**CSS代码语法,CSS 放置位置,CSS的继承,选择器的种类/优先级,背景样式,字体样式,文本属性,基本样式,样式重置,盒模型样式,浮动float,定位position,浏览器默认样式

HTML5 /CSS3

**HTML5:**HTML5 的优势,HTML5 废弃元素,HTML5 新增元素,HTML5 表单相关元素和属性

**CSS3:**CSS3 新增选择器,CSS3 新增属性,新增变形动画属性,3D变形属性,CSS3 的过渡属性,CSS3 的动画属性,CSS3 新增多列属性,CSS3新增单位,弹性盒模型

JavaScript

**JavaScript:**JavaScript基础,JavaScript数据类型,算术运算,强制转换,赋值运算,关系运算,逻辑运算,三元运算,分支循环,switch,while,do-while,for,break,continue,数组,数组方法,二维数组,字符串

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img

象是没有x属性的,故访问时输出undefined;而访问b.x的时候,将输出旧对象的x的值,即{n:2}。

7、下面代码的输出是什么?

function checkAge(data) {

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-f9Ss3Rzy-1712482251035)]
[外链图片转存中…(img-RsceNVvp-1712482251036)]
[外链图片转存中…(img-RvGFrif5-1712482251036)]
[外链图片转存中…(img-7Tmk0UqD-1712482251037)]
[外链图片转存中…(img-SH46cWKP-1712482251038)]
[外链图片转存中…(img-YQt5yAd1-1712482251038)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-aS9HnY4P-1712482251039)]

学习笔记

主要内容包括html,css,html5,css3,JavaScript,正则表达式,函数,BOM,DOM,jQuery,AJAX,vue等等

HTML/CSS

**HTML:**HTML基本结构,标签属性,事件属性,文本标签,多媒体标签,列表 / 表格 / 表单标签,其他语义化标签,网页结构,模块划分

**CSS:**CSS代码语法,CSS 放置位置,CSS的继承,选择器的种类/优先级,背景样式,字体样式,文本属性,基本样式,样式重置,盒模型样式,浮动float,定位position,浏览器默认样式

[外链图片转存中…(img-m5MfBpcP-1712482251039)]

HTML5 /CSS3

**HTML5:**HTML5 的优势,HTML5 废弃元素,HTML5 新增元素,HTML5 表单相关元素和属性

**CSS3:**CSS3 新增选择器,CSS3 新增属性,新增变形动画属性,3D变形属性,CSS3 的过渡属性,CSS3 的动画属性,CSS3 新增多列属性,CSS3新增单位,弹性盒模型

[外链图片转存中…(img-lczUcJ51-1712482251039)]

JavaScript

**JavaScript:**JavaScript基础,JavaScript数据类型,算术运算,强制转换,赋值运算,关系运算,逻辑运算,三元运算,分支循环,switch,while,do-while,for,break,continue,数组,数组方法,二维数组,字符串

[外链图片转存中…(img-3WHkfV4O-1712482251040)]

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-y1XLKGip-1712482251040)]

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值