前端基础面试题

null 和 undefined 的区别,如何让一个属性变为null

undefined 表示一个变量自然的、最原始的状态值,而 null 则表示一个变量被人为的设置为空对象,而不是原始状态。所以,在实际使用过程中,为了保证变量所代表的语义,不要对一个变量显式的赋值 undefined,当需要释放一个对象时,直接赋值为 null 即可。

undefined 的字面意思就是:未定义的值 。这个值的语义是,希望表示一个变量最原始的状态,而非人为操作的结果 。 这种原始状态会在以下 4 种场景中出现:

  1. 声明了一个变量,但没有赋值

  1. 访问对象上不存在的属性

  1. 函数定义了形参,但没有传递实参

  1. 使用 void 对表达式求值

因此,undefined 一般都来自于某个表达式最原始的状态值,不是人为操作的结果。当然,你也可以手动给一个变量赋值 undefined,但这样做没有意义,因为一个变量不赋值就是 undefined 。

null 的字面意思是:空值 。这个值的语义是,希望表示 一个对象被人为的重置为空对象,而非一个变量最原始的状态 。 在内存里的表示就是,栈中的变量没有指向堆中的内存对象

数组和伪数组的区别

伪数组与数组的区别就是它们的_proto_区别,

普通数组有很多数组的方法,比如说push,shift,map等等

而伪数组却没有,所以我们称这类解构类似数组却没有数组方法的集合叫做伪数组。

数组和伪数组的区别

  1. 伪数组是一个对象(Object),而真实的数组是一个数组(Array)也是对象

  1. 拥有length属性,且必须是number类型,其它属性(索引)为字符串

  1. 不具有数组所具有的方法,forEach()等,不过有Object的方法

  1. 伪数组长度不可变,真数组长度可以变

  1. 可以通过for in遍历

  1. 伪数组没有Array.prototype,它只是一个对象

判断是否是数组

Array.isArray(arr) //true

arr instanceof Array //true

常见的伪数组
  1. 参数数组:arguments

  1. DOM对象列表HTMLCollection():比如通document.getElementsByTagName得到的列表, 通过 document.getElementByTags 获取的 dom元素

  1. jquery对象:比如$(“div”)

伪数组存在的意义

让一些对象也可以使用数组方法,可以通过call() bind() apply()方法实现

  • 注意,方法的返回值类型不会改变,返回数组的还是会返回数组

伪数组转换为真数组
  1. 使用ES6中的Array.from方法

  1. 使用扩展运算符,也是ES6的语法

  1. 使用Array.prototype.slice.call();

arr = Array.prototype.slice.call(fakeArray)

  1. 使用[].slice.call()

var arr = [].slice.call(fakeArray)

// 伪数组
var arrLike = {
    0: 'a',
    1: 'b',
    2: 'c',
    length: 3,
};

伪数组转为真数组

var arr = [];
for(var i = 0; i < arrLike.length; i++){
   arr.push(arrLike[i]);
}
  1. 利用数组的slice()方法

;[].slice.call(arrLike);
//slice() 方法以新的数组对象,返回数组中被选中的元素。
  1. 类数组转换为数组

  • 转换方法

  • 使用Array.from()

  • 使用Array.prototype.slice.call()

  • 使用Array.prototype.forEach()进行属性遍历并组成新的数组

  • 转换须知

  • 转换后的数组长度由length属性决定。索引不连续时转换结果是连续的,会自动补位。

  • 代码示例

let al1 = {
    length: 4,
    0: 0,
    1: 1,
    3: 3,
    4: 4,
    5: 5,
};
console.log(Array.from(al1)) // [0, 1, undefined, 3]
js 中有哪几种内存泄露的情况
  1. 意外的全局变量;

  1. 闭包;

  1. 未被清空的定时器;

  1. 未被销毁的事件监听;

  1. DOM 引用;

call appy bind的作用和区别

都可以改变函数内部的this指向。

区别点:

  1. call 和 apply 会调用函数,并且改变函数内部this指向。

  1. call 和 apply 传递的参数不一样,call 传递参数arg1,arg2...形式 apply 必须数组形式[arg]

  1. bind 不会调用函数,可以改变函数内部this指向。

call 的主要作用也可以实现继承

function Person(uname, age) {
    this.uname = uname;
    this.age = age;
  }
  function Son(uname, age) {
    Person.call(this, uname, age);
  }
  var son = new Son("zhang", 12);
  console.log(son);

apply方法

apply()方法调用一个函数。简单理解为调用函数的方式,但是它可以改变函数的this指向。

写法:fun.apply(thisArg, [argsArray])

  • thisArg:在fun函数运行时指定的this值

  • argsArray:传递的值,必须包含在数组里面

  • 返回值就是函数的返回值,因为他就是调用函数

apply的主要应用,比如可以利用apply可以求得数组中最大值

const arr = [1, 22, 3, 44, 5, 66, 7, 88, 9];
const max = Math.max.apply(Math, arr);
console.log(max)

bind方法

bind()方法不会调用函数,但是能改变函数内部this指向

写法:fun.bind(thisArg, arg1, arg2, ...)

  • thisArg:在fun函数运行时指定的this值

  • arg1,arg2:传递的其他参数

  • 返回由指定的this值和初始化参数改造的原函数拷贝

var o = {
    name: "lisa"
};
function fn() {
    console.log(this);
}
var f = fn.bind(o);
f();

bind应用

如果有的函数我们不需要立即调用,但是又需要改变这个函数的this指向,此时用bind再合适不过了

const btns = document.querySelectorAll("button");
for (let i = 0; i < btns.length; i++) {
    btns[i].onclick = function() {
      this.disabled = true;
      setTimeout(
        function() {
          this.disabled = false;
        }.bind(this),
        2000
      );
    };
}

扩展:

主要应用场景:

  1. call 经常做继承。

  1. apply 经常跟数组有关系,比如借助于数学对象实现数组最大值最小值。

  1. bind 不调用函数,但是还想改变this指向,比如改变定时器内部的this指向。

this指向(普通函数、箭头函数)

普通函数中的this

  1. 谁调用了函数或者方法,那么这个函数或者对象中的this就指向谁

   let getThis = function () {
            console.log(this);
        }

        let obj={
            name:"Jack",
            getThis:function(){
                console.log(this);
            }
        }
        //getThis()方法是由window在全局作用域中调用的,所以this指向调用该方法的对象,即window
        getThis();//window
        //此处的getThis()方法是obj这个对象调用的,所以this指向obj
        obj.getThis();//obj
  1. 匿名函数中的this:匿名函数的执行具有全局性,则匿名函数中的this指向是window,而不是调用该匿名函数的对象;

       let obj = {
            getThis: function () {
                return function () {
                    console.log(this);
                }
            }
        }
        obj.getThis()(); //window

箭头函数中的this

  1. 箭头函数中的this是在函数定义的时候就确定下来的,而不是在函数调用的时候确定的;

  1. 箭头函数中的this指向父级作用域的执行上下文;(技巧:因为javascript中除了全局作用域,其他作用域都是由函数创建出来的,所以如果想确定this的指向,则找到离箭头函数最近的function,与该function平级的执行上下文中的this即是箭头函数中的this

  1. 箭头函数无法使用apply、call和bind方法改变this指向,因为其this值在函数定义的时候就被确定下来。

        let obj = {
            //此处的this即是箭头函数中的this
            getThis: function () {
                return  ()=> {
                    console.log(this);
                }
            }
        }
        obj.getThis()(); //obj

例2:该段代码中存在两个箭头函数,this找不到对应的function(){},所以一直往上找直到指向window。

//代码中有两个箭头函数,由于找不到对应的function,所以this会指向window对象。

       let obj = {
            getThis: ()=> {
                return  ()=> {
                    console.log(this);
                }
            }
        }
        obj.getThis()(); //window
new会发生什么
  1. 在内存创建一个新对象

  1. 把构造函数中this指向新建的对象

  1. 会在新对象上添加一个__proto__属性,指向函数的原型对象prototype

  1. 判断函数返回值,如果值是引用类型就直接返回值;否则返回this(创建的新对象)

对象的继承是通过原型链,而原型链就是通过__proto__一层一层的往上找而形成的链式结构,直到最后找到null。

那么new的过程发生了什么?

1、new先创建了一个空对象

var news = new Object()

2、我们将这个空对象的__proto__属性指向whatnew构造函数的prototype属性,使两者都有共同的原型对象whatnew.prototype,因此空对象可以访问whatnew函数

new.__proto__ = whatnew.prototype

3、修改whatnew的this到object上面,call/apply,并把参数传入

4、最后把object返回给mynew就可以了

实现一个new方法

function Mynew(fun, ...arg) {
  let obj = {
        __proto__: fun.prototype 
  }  
  fun.apply(obj, arg)
  return obj    
}

function person(age, name) {
  this.age = age
  this.name = name    
}

let mynew = Mynew(person, 18, '小明')

// 1. 创建空对象;
var obj = {};
// 2. 设置新对象的 constructor 属性为构造函数的名称,设置新对象的__proto__属性指向构造函数的 prototype 对象;
obj.__proto__ = ClassA.prototype;
// 3. 使用新对象调用函数,函数中的 this 被指向新实例对象:
ClassA.call(obj); //{}.构造函数();
// 4. 如果无返回值或者返回一个非对象值,则将新对象返回;如果返回值是一个新对象的话那么直接直接返回该对象。

来看下面几道题

function fn() {
	this.user = '111'
}
var a = new fn()
console.log(a.user) // 111
function fn() {
	this.user = '111'
	return {}
}
var a = new fn()
console.log(a.user) // undefined,因为{}对象上没有user属性
function fn() {
	this.user = '111'
	return undefined
}
var a = new fn()
console.log(a.user) // 111
function fn() {
	this.user = '111'
	return null
}
var a = new fn()
console.log(a.user) // 111

类和对象

类,是指将相同属性的东西放在放在一起,类是一个模板,能够描述一类对象的状态和行为

而对象,就是实际存在某个类中的一个个的个体,所以也被称为实例(instance)。

对象的抽象是类,类的具体化就是对象,也就是类的实例就是对象。

link 和 @import 的区别
  1. 引入的内容不同

link 除了引用样式文件,还可以引用图片等资源文件,而 @import 只引用样式文件

  1. 加载顺序不同

link 引用 CSS 时,在页面载入时同时加载;@import 需要页面网页完全载入以后加载

  1. 兼容性不同

link 是 XHTML 标签,无兼容问题;@import 是在 CSS2.1 提出的,低版本的浏览器不支持

  1. 对 JS 的支持不同

link 支持使用 Javascript 控制 DOM 去改变样式;而 @import 不支持

为什么link用href获取资源 script和img用src

src用于替换当前元素,href用于在当前文档和引用资源之间确立联系。

src

  • src是source的缩写,指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置;在请求src资源时会将其指向的资源下载并应用到文档内,例如js脚本,img图片和frame等元素

<script src ="js.js"></script>

当浏览器解析到该元素时,会暂停其他资源的下载和处理,直到将该资源加载、编译、执行完毕,图片和框架 等元素也如此,类似于将所指向资源嵌入当前标签内。这也是为什么将js脚本放在底部而不是头部

href

  • href是Hypertext Reference的缩写,指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接

  • 在文档中添加link标签,浏览器会识别该文档为css文件,就会并行下载资源并且不会停止对当前文档的处理。这也是为什么建议使用link方式来加载css,而不是使用@import方式

<link href="common.css" rel="stylesheet"/>

为什么 JS 是单线程, 而不是多线程 [常考]

单线程是指 JavaScript 在执行的时候,有且只有一个主线程来处理所有的任务。

目的是为了实现与浏览器交互。

我们设想一下,如果 JavaScript 是多线程的,现在我们在浏览器中同时操作一个

DOM,一个线程要求浏览器在这个 DOM 中添加节点,

而另一个线程却要求浏览器删掉这个 DOM 节点,

那这个时候浏览器就会很郁闷,他不知道应该以哪个线程为准。

所以为了避免此类现象的发生,降低复杂度,JavaScript

选择只用一个主线程来执行代码,以此来保证程序执行的一致性。

请解释一下什么是防抖与节流

  • 防抖(debounce)

  1. 总结:就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

  • 节流(throttle)

什么是函数节流?介绍一下应用场景和原理?

函数节流(throttle)是指阻止一个函数在很短期间隔内连续调用。 只有当上一次函数执行后达到规定的时间间隔,才能进行下一次调用。 但要保证一个累计最小调用间隔(不然拖拽类的节流都将无连续效果)

函数节流用于 onresize, onscroll 等短期内会屡次触发的事件

函数节流的原理:使用定时器作时间节流。 当触发一个事件时,先用 setTimout 让这个事件延迟一小段时间再执行。 若是在这个时间间隔内又触发了事件,就 clearTimeout 原来的定时器, 再 setTimeout 一个新的定时器重复以上流程。

函数节流简单实现:

functionthrottle(method, context){ 
    clearTimeout(methor.tId); 
    method.tId = setTimeout(function(){ 
        method.call(context); 
    }, 100); // 两次调用至少间隔 100ms 
} 
// 调用 window.onresize = function(){ 
   throttle(myFunc, window); 
}
  1. 总结:就是每次触发事件的隔间至少要大于等于n秒,不会重置计时

请描述一下var、const、let三者的区别

var可以变量提升,const、let不会

var没有块级作用域,const、let存在块级作用域

var可以重复定义变量,const、let不能重复定义

var定义的变量会作为window对象的属性,let与const定义的变量不会

const需要有初始值,并且值不能修改(定义的是常量)

使用箭头函数应注意什么?

  1. 箭头函数的this指向父级函数的this,如果没有父级则指向window

  1. 不能够使用arguments对象

  1. 不能用作构造函数,这就是说不能够使用new命令,否则会抛出一个错误

  1. 不可以使用yield命令,因此箭头函数不能用作 Generator 函数

es5和es6的区别,说一下你所知道的es6

let声明变量和const声明常量,两个都有块级作用域ES5中是没有块级作用域的,并且var有变量提升,在let中,使用的变量一定要进行声明

箭头函数ES6中的函数定义不再使用关键字function(),而是利用了()=>来进行定义

字符串模板字符串是增强版的字符串,用反引号标识,可以当作普通字符串使用,也可以用来定义多行字符串

解构赋值ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值

for...of循环可以遍历数组、Set和Map结构、某些类似数组的对象、对象,以及字符串

import、export模块化导入导出ES6标准中,Js原生支持模块(module)。将JS代码分割成不同功能的小块进行模块化,将不同功能的代码分别写在不同文件中,各模块只需导出公共接口部分,然后通过模块的导入的方式可以在其他地方使用

Set数据结构,类似数组。所有的数据都是唯一的,没有重复的值。它本身是一个构造函数

展开运算符可以将数组或对象里面的值展开;还可以将多个值收集为一个变量

class 类的继承ES6中不再像ES5一样使用原型链实现继承,而是引入Class这个概念

async、await使用 async/await, 搭配promise,可以通过编写形似同步的代码来处理异步流程, 提高代码的简洁性和可读性async 用于申明一个 function 是异步的,而 await 用于等待一个异步方法执行完成

Promise是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理、强大

Symbol是一种基本类型。Symbol 通过调用symbol函数产生,它接收一个可选的名字参数,该函数返回的symbol是唯一的

Proxy代理使用代理(Proxy)监听对象的操作,然后可以做一些相应事情

理解 async/await 以及对 Generator 的优势

async/await的介绍:

async await 是用来解决异步的,async函数是Generator函数的语法糖

使用关键字async来表示,在函数内部使用 await 来表示异步

async函数返回一个 Promise 对象,可以使用then方法添加回调函数

当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,

再接着执行函数体内后面的语句

async较Generator的优势:

(1)内置执行器。Generator 函数的执行必须依靠执行器,而 Aysnc 函数自带执行器,

调用方式跟普通函数的调用一样

(2)更好的语义。async 和 await 相较于 * 和 yield 更加语义化  

(3)返回值是 Promise。async 函数返回的是 Promise 对象,

比Generator函数返回的Iterator对象方便,可以直接使用 then() 方法进行调用

箭头函数与普通函数区别?

  1. 写法不一样

  1. 普通函数存在提升的现象

  1. 箭头函数不能作为构造函数使用

  1. 两者this的指向不同

  1. 箭头函数本身没有arguments对象

  1. 箭头函数没有new.target

说出至少5个ES6的新特性,并简述它们的作用。(简答题)

let关键字,用于声明只在块级作用域起作用的变量。

const关键字,用于声明一个常量。

结构赋值,一种新的变量赋值方式。常用于交换变量值,提取函数返回值,设置默认值。

Symbol数据类型,定义一个独一无二的值。

Proxy代理,用于编写处理函数,来拦截目标对象的操作。

for...of遍历,可遍历具有iterator 接口的数据结构。

Set结构,存储不重复的成员值的集合。

Map结构,键名可以是任何类型的键值对集合。

Promise对象,更合理、规范地处理异步操作。

Class类定义类和更简便地实现类的继承。

ajax请求的时候get 和post方式的区别

(1)get请求

参数要跟在url后面

安全性不高

传输数据比较小,但速度快

一般用于获取,删除

(2)post请求

参数会放在请求体中,

安全性相对高些

传输数据大,但相对速度慢些

post一般用于修改或者添加

什么是jsonp

  • jsonp是一种解决跨域请求问题的技术

  • 不足点:它只能是get请求

continue 与 break的区别

  • continue:跳过本次循环,直接进入下一次循环

  • break:直接终止循环

图片img标签title与alt属性的区别

  • title属性:光标移入要显示图片文字

  • alt属性:当图片加载失败时要显示的文字

每个 HTML 文件头里都有个很重要的东西,Doctype,知道这是干什么的么?

告知浏览器文档使用哪种 HTML 或 XHTML 规范

浏览器本身分为两种模式,一种是标准模式,一种是怪异模式,浏览器通过 doctype 来区分这两种模式,doctype 在 html

中的作用就是触发浏览器的标准模式,否则为怪异模式;

不同浏览器在怪异模式下会有一些不同的表现,不建议使用怪异模式;

doctype一定需要写html上面才会生效;

title 与 h1 的区别、b 与 strong 的区别、i 与 em 的区别?

  • title:表示文档窗口标题

  • h1:内容标题

  • b:粗体

  • strong:粗体(strong会表示强调)(语义化)

  • i:斜体

  • em:斜体(em会表示强调,强调比strong弱)(语义化)

CSS 隐藏元素的几种方法(至少说出三种)

Opacity: 0 ----设置透明度来隐藏元素

visibility:hidden; --- 隐藏对应的元素并且挤占该元素原来的空间。

display:none; ----隐藏对应的元素但不挤占该元素原来的空间。

position:absolute; top:-9999px; ---让该元素脱离文档流移出视觉区域.

rgba()和 opacity 的透明效果有什么不同?

答案:

相同点 : rgba()和 opacity 都能实现透明效果,

不同点 : 但最大的不同是 opacity 作用于元素,以及元素内的所有内容的透明度,而 rgba()只作用于元素的颜色或其背景色。(设置 rgba 透明的元素的子元素不会继承透明效果!)

哪些 css 属性可以继承?

答案:

可继承:text-align、font、color、line-height、letter-spacing、word-spacing、text-indent

不可继承 :border padding margin width height ;

请说一下你用过的浏览器存储,并说出它们的区别?

sessionStorage

localStorage

cookie

相同点 : 三者都是在浏览器本地存放数据;

区别 :

sessionStorage:数据只存在于会话期间

localStorage:数据永久存储

cookie:数据默认会话结束时过期,但可以设置过期时间,在请求服务端,浏览器会默认把cookie数据发送给服务器,cookie能存放的数据相对较小

json和jsonp的区别?

  • json是一种数据格式,一般用于数据交互;

  • jsonp是一种解决跨域请求技术,只能是get请求;

jsonp的实现原理

  • 利用script请求并且执行服务端响应的代码;

  • 执行代码调用页面中的函数,且把代码中数据传入

解决跨域问题:

1.添加请求头,后端添加请求头 access-control-allow-origin:* 跨域的地址

2.前端也可以添加请求头 setRequestHeader

3.jsonp形式,利用 link script ifarme 这个标签不受跨域的影响,利用script标签(只能解决get请求跨域),利用了script标签链接对应的地址, 然后让这个链接的地址给我们执行访问

Jsonp(页面访问形式)解决跨域

JSONP的方法,需要后端的支持

script 标签不遵从跨域 ,所以我们可以内部访问 js添加我们对应的方法, 执行我们对应的传入的方法

1.创建方法,回调方法

2.将方法设置到window里面

3.将方法名和对应方法传入,如果需要参数传入对应的参数

function a(str){

}

//给窗口添加一个方法

window['abc']= a

window.cb() //调用窗口的方法

let promise = ajax({

url:"https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?cb=abc&wd=hello"

})

promise.then((res)=>{

console.log(res)

})

promise.catch((err)=>{

console.log(err)

})

jsonp封装

function jsonp({
    url, //链接地址
    params,//参数 对象类型
    callbackName,//回调函数名字
    callback //回调函数
}){
    //1.给window添加方法 方法名应该不能重复
    //随机生成一个函数名
    let fnName = "fn"+Date.now()+Math.ceil(Math.random()*10000)
    //将对应回调函数添加给window 添加的函数名随机生成
    window[fnName] = callback
    //2.添加script
    let script = document.createElement('script')
    //3.将方法名拼接到url地址后面
    url += `?${callbackName}=${fnName}`
    //4.将参数再做拼接
    let paramsStr = joinParams(params)
    url += paramsStr
    //5.将这个url地址给script标签 src属性
    script.src = url
    //6.将script加给body
     document.body.appendChild(script)
    //判断是否已经加载成功
    script.onload = function(){
        script.remove()
        delete window[fnName] 
    }
}
function joinParams(params){
      let str = ""
      //取出对象里面的值
      for(let key in params){
        str+=`&${key}=${params[key]}`
    }
    return str
}

解构赋值过程 及其原理

答案:

解构赋值:其实就是分解出一个对象的解构,分成两个步骤:

解构赋值过程:

变量的声明

变量的赋值

原理:

ES6 变量的解构赋值本质上是“模式匹配”,只要等号两边的模式相同,

左边的变量就会被赋予匹配的右边的值,

如果匹配不成功变量的值就等于 undefined

BOM

BOM(浏览器对象模型)是浏览器自己的一些信息的设置和获取,例如获取浏览器的宽度、高度,设置让浏览器跳转到哪一个地址。

navigator: 获取浏览器特性(即俗称的UA)而后识别客户端

location: 获取网址、协议、path、参数、hash 等

history: 操做浏览器的历史纪录,(前进,后退等功能)

1.什么是window对象? 什么是document对象?

window:它是一个顶层对象,而不是另外一个对象的属性,即浏览器的窗口。

document:表明整个HTML 文档,可用来访问页面中的全部元素

Window 对象表示当前浏览器的窗口,是JavaScript的顶级对象。咱们建立的全部对象、函数、变量都是 Window 对象的成员。

Window 对象的方法和属性是在全局范围内有效的。

Document 对象是 HTML 文档的根节点与全部其余节点(元素节点,文本节点,属性节点, 注释节点)

Document 对象使咱们能够经过脚本对 HTML 页面中的全部元素进行访问

Document 对象是 Window 对象的一部分,可经过 window.document 属性对其进行访问

解释一下事件代理

事件代理的原理其实就和做用域链的原理差很少,可是事件代理是利用事件的冒泡原理来实现的,事件代理就是经过给祖先元素添加事件,经过事件目标对象开始向上查找找到匹配的子节点为止,若是找不到则到绑定事件的那个祖先元素为止,找到了就触发事件,而且能够经过js中call和apply来改变触发事件函数中的this为当前绑定节点,也是经过一层一层逐层向上的方式进行匹配查找而触发对应事件,好处就是可使后添加的dom元素也一样有以前存在元素的事件,jquery中可使用on,delegate,live实现的,不过在jquery1.7版本之后吧live给废除了,缘由就是live绑定事件的祖先元素是整个html页面的根节点,因此性能消耗比较大,在后边的版本中给删除了,使用on,delegate代替

优势:

使代码简洁

减小浏览器的内存占用

缺点:

使用不当会形成事件在不该该触发时触发

阻止冒泡
  • 在W3c中,使用stopPropagation()方法

  • 在IE下设置cancelBubble = true;

阻止捕获

阻止事件的默认行为,例如click 后的跳转

  • 在W3c中,使用preventDefault()方法;

  • 在IE下设置window.event.returnValue = false;

attribute和property的区别是什么?

attribute是dom元素在文档中做为html标签拥有的属性;

property就是dom元素在js中做为对象拥有的属性。

谈谈This对象的理解。

this分为几个不一样的使用场景,在function中this指的的是window,若是是实用new 调用的话this指的是当前的实例化对象,在事件调用函数中this指的调用事件的window特殊的是在IE中的attachEvent中的this老是指向全局对象Window;,在定时器中this指的是window,在es6中有一个箭头函数,在箭头函数中this永远指向的是父级对象,this也是能够改变的,在js中call, apply, bind均可以改变this的指向, call, apply都是执行一个函数而且改变this,区别就是参数传递不同,而bind是返回一个绑定this以后的新函数

javascript 代码中的"use strict";是什么意思 ? 使用它区别是什么?

use strict是一种ECMAscript 5 添加的(严格)运行模式,这种模式使得 Javascript 在更严格的条件下运行,

使JS编码更加规范化的模式,消除Javascript语法的一些不合理、不严谨之处,减小一些怪异行为。

默认支持的糟糕特性都会被禁用,好比不能用with,也不能在乎外的状况下给全局变量赋值;

全局变量的显示声明,函数必须声明在顶层,不容许在非函数代码块内声明函数,arguments.callee也不容许使用;

消除代码运行的一些不安全之处,保证代码运行的安全,限制函数中的arguments修改,严格模式下的eval函数的行为和非严格模式的也不相同;

提升编译器效率,增长运行速度;

为将来新版本的Javascript标准化作铺垫。

检测浏览器版本版本有哪些方式?

根据 navigator.userAgent // UA.toLowerCase().indexOf('chrome')

根据 window 对象的成员 // 'ActiveXObject' in window

说说对es6的理解(说一下es6,知道es6吗)

语法糖(箭头函数,类的定义,继承),以及一些新的扩展(数组,字符串,对象,方法等),对做用域的从新定义,以及异步编程的解决方案(promise,async,await)、解构赋值的出现

2.ES6经常使用特性

变量定义(let和const,可变与不可变,const定义对象的特殊状况)

解构赋值

模板字符串

数组新API(例:Array.from(),entries(),values(),keys())

箭头函数(rest参数,扩展运算符,::绑定this)

Set和Map数据结构(set实例成员值惟一存储key值,map实例存储键值对(key-value))

Promise对象(前端异步解决方案进化史,generator函数,async函数)

Class语法糖(super关键字)

ES6 class 和普通构造函数的区别

class 其实一直是 JS 的关键字(保留字),可是一直没有正式使用,直到 ES6 。 ES6 的 class 就是取代以前构造函数初始化对象的形式,从语法上更加符合面向对象的写法

1)class 是一种新的语法形式,是class Name {...}这种形式,和函数的写法彻底不同

2)二者对比,构造函数函数体的内容要放在 class 中的constructor函数中,constructor即构造器,初始化实例时默认执行

3)class 中函数的写法是add() {...}这种形式,并无function关键字

并且使用 class 来实现继承就更加简单了

在class中直接extends关键字就能够实现继承,而不像以前的继承实现有多种不一样的实现方式,在es6中就只有一种

注意如下两点:

使用extends便可实现继承,更加符合经典面向对象语言的写法,如 Java

子类的constructor必定要执行super(),以调用父类的constructor

ES6 中新增的数据类型有哪些?

Set 和 Map 都是 ES6 中新增的数据结构,是对当前 JS 数组和对象这两种重要数据结构的扩展。因为是新增的数据结构

1)Set 相似于数组,但数组能够容许元素重复,Set 不容许元素重复

2)Map 相似于对象,但普通对象的 key 必须是字符串或者数字,而 Map 的 key 能够是任何数据类型

前端安全

1.XSS(Cross Site Scripting,跨站脚本攻击)

这是前端最多见的攻击方式,不少大型网站(如 Facebook)都被 XSS 攻击过。

举一个例子,我在一个博客网站正常发表一篇文章,输入汉字、英文和图片,彻底没有问题。可是若是我写的是恶意的 JS 脚本,例如获取到document.cookie而后传输到本身的服务器上,那我这篇博客的每一次浏览都会执行这个脚本,都会把访客 cookie 中的信息偷偷传递到个人服务器上来。

其实原理上就是黑客经过某种方式(发布文章、发布评论等)将一段特定的 JS 代码隐蔽地输入进去。而后别人再看这篇文章或者评论时,以前注入的这段 JS 代码就执行了。JS 代码一旦执行,那可就不受控制了,由于它跟网页原有的 JS 有一样的权限,例如能够获取 server 端数据、能够获取 cookie 等。因而,攻击就这样发生了。

XSS的危害

XSS 的危害至关大,若是页面能够随意执行别人不安全的 JS 代码,轻则会让页面错乱、功能缺失,重则会形成用户的信息泄露。

好比早些年社交网站常常爆出 XSS 蠕虫,经过发布的文章内插入 JS,用户访问了感染不安全 JS 注入的文章,会自动从新发布新的文章,这样的文章会经过推荐系统进入到每一个用户的文章列表面前,很快就会形成大规模的感染。

还有利用获取 cookie 的方式,将 cookie 传入入侵者的服务器上,入侵者就能够模拟 cookie 登陆网站,对用户的信息进行篡改。

XSS的预防

那么如何预防 XSS 攻击呢?—— 最根本的方式,就是对用户输入的内容进行验证和替换,须要替换的字符有:

& 替换为:&

< 替换为:<

替换为:>
” 替换为:"
‘ 替换为:'
/ 替换为:/
替换了这些字符以后,黑客输入的攻击代码就会失效,XSS 攻击将不会轻易发生。

除此以外,还能够经过对 cookie 进行较强的控制,好比对敏感的 cookie 增长http-only限制,让 JS 获取不到 cookie 的内容。

2.CSRF(Cross-site request forgery,跨站请求伪造)

CSRF 是借用了当前操做者的权限来偷偷地完成某个操做,而不是拿到用户的信息。

例如,一个支付类网站,给他人转帐的接口是http://buy.com/pay?touid=999&...,而这个接口在使用时没有任何密码或者 token 的验证,只要打开访问就直接给他人转帐。一个用户已经登陆了http://buy.com,在选择商品时,忽然收到一封邮件,而这封邮件正文有这么一行代码<img src="http://buy.com/pay?touid=999&amp;money=100"/>,他访问了邮件以后,其实就已经完成了购买。

CSRF 的发生实际上是借助了一个 cookie 的特性。咱们知道,登陆了http://buy.com以后,cookie 就会有登陆过的标记了,此时请求http://buy.com/pay?touid=999&... cookie 的,所以 server 端就知道已经登陆了。而若是在http://buy.com去请求其余域名的 API 例如http://abc.com/api时,是不会带 cookie 的,这是浏览器的同源策略的限制。可是 —— 此时在其余域名的页面中,请求http://buy.com/pay?touid=999&...,会带着buy.com的 cookie ,这是发生 CSRF 攻击的理论基础。

预防 CSRF 就是加入各个层级的权限验证,例如如今的购物网站,只要涉及现金交易,确定要输入密码或者指纹才行。除此以外,敏感的接口使用POST请求而不是GET也是很重要的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
前端基础面试题2021 pdf》是一份前端开发面试题目集合的PDF文件。这份题目集合包含了2021年前端开发领域的基础知识和技能要求。 这份PDF文件主要包括了以下内容:HTML、CSS、JavaScript基础知识、网络与安全、框架与工具、性能优化与调试、前端工程化等方面的题目。 在HTML方面,题目涉及HTML标签、常见元素的使用、语义化等内容。在CSS方面,题目包括选择器、盒模型、浮动、定位、布局等知识。在JavaScript方面,题目涉及变量、数据类型、运算符、函数、作用域、闭包、面向对象等内容。 此外,网络与安全的题目涵盖了HTTP协议、HTTPS、跨域、攻击与防御等知识。框架与工具方面,题目包括对常见框架如React、Vue的理解、webpack等工具的使用。性能优化与调试的题目涉及浏览器渲染原理、代码优化、性能测试等。而前端工程化方面的题目则包括项目构建、版本控制、代码规范等方面。 通过研究这份面试题目集合,考生可以了解2021年前端开发领域的基本要求和技能点,提前进行准备和复习。同时,这份题目集合也可以帮助面试官评估候选人的技术水平和能力,从而做出合理的招聘决策。 总的来说,《前端基础面试题2021 pdf》是一份在前端开发领域进行面试准备和评估的有用资源。如果你是一位前端开发者,阅读并解答其中的题目,有助于加深对前端知识和技能的理解和掌握。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值