JavaScript基础面试题总结

JavaScript基础面试题总结

写JavaScript的基本规范

  • 不要在同一行声明多个变量
  • 使用 === / !==来比较true/false或者数值
  • 使用对象字面量来代替new Array这种形式
  • 不要使用全局函数
  • switch语句必须带default分支
  • If语句必须使用大括号
  • for-in循环中的变量应该使用var关键字明确限定作用域,从而避免作用污染

JavaScript代码中的“use strict”是什么意思?使用它区别是什么?

use strict 是一种ECMscript添加的严格运作模式,这种运作模式使得JavaScript在更严格的条件下运行,使得JS编码更加规范化的模式,消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为。

严格模式的限制

  • 变量必须声明后再使用
  • 函数的参数不能有同名的属性,否则报错
  • 不能使用with语句
  • 禁止this指向全局对象

渐进增强和优雅降级

渐进增强:针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能,达到更好的用户体验。
优雅降级:一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。

JS数据类型

基本数据类型:string、number、boolean、null、undefined
复杂数据类型:Object( 引用数据类型:Object、Array、Function)

typeof能正确区分原始值吗?

	typeof 并不能够准确判断类型,对于原始类型来说,除了null之外,都能正确的显示类型,对于对象来说除了function之外都会判断为object;

介绍js有哪些内置对象?

Object 是 JavaScript 中所有对象的父对象

数据封装类对象:Object、Array、Boolean、Number 和 String
其他对象:Function、Arguments、Math、Date、RegExp、Error

JavaScript原型,原型链 ? 有什么特点?

原型:每个对象都会在其内部初始化一个属性,就是prototype(原型)。
原型链:当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype,于是就这样一直找下去,也就是我们平时所说的原型链的概念。
关系:instance.constructor.prototype = instance.proto
特点:JavaScript对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变。

Javascript如何实现继承?

  1. 构造继承

  2. 原型继承

  3. 实例继承

  4. 拷贝继承
    构造函数与原型混合方式:
    function Parent(){
    this.name = ‘wang’;
    }

    function Child(){
    this.age = 28;
    }
    Child.prototype = new Parent();//继承了Parent,通过原型

    var demo = new Child();
    alert(demo.age);
    alert(demo.name);//得到被继承的属性

JavaScript创建对象的几种方式

  • 对象字面量的方式
    person = {fristname:‘mark’,lastname:‘Yun’,age:25,eyecolor:‘black’}
  • 用function来模拟无参的构造函数
    function Person(){}
    var person = new Person()
    person.name = “Mark”
    person.age = “25”
    person.work = function(){
    alert(person.name + “hello”)
    }
    person.work()
  • 用function来模拟有参构造函数实现(用this关键字定义构造的上下文属性)
    function Pet(name,age,habby){
    this.name = name;
    this.age = age;
    this.habby = habby;
    this.eat = function(){
    alert(this.name + this.age + this.habby)
    }
    }
    var aaa = new Pet(“aa”,20,“coding”)
    aaa.eat()
  • 用工厂方式来创建
    var dog = new Object()
    dog.name = “dogs”
    dog.age = 2
    dog.work = function(){
    alert(dog.name + dog.age + “汪汪”)
    }
    dog.work()
  • 用原型方式来创建
    function Dog(){}
    Dog.prototype.name = “旺财”
    Dog.prototype.eat = function(){
    alert(this.name + “是个吃货”)
    }
  • 用混合方式来创建
    function Car(name,price){
    this.name = name;
    this.price = price;
    }
    Car.prototype.sell = function(){
    alert(this.name + this.price + “卖出去了”)
    }
    var cars = new Car(“宝马”,200000)
    cars.sell()

Javascript作用链域

作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,到window对象即被终止,作用域链向下访问变量是不被允许的。
简单的说,作用域就是变量和函数的可访问范围,即作用域控制着变量和函数的可见性和生命周期。

解释什么是事件代理?

事件代理,又称为事件委托,是JavaScript中常用绑定事件的常用技巧。
事件代理是把原本需要绑定的事件委托给父元素,让父元素担当事件监听的职务。
事件代理的原理是DOM元素的事件冒泡。
优点:可以大量节省内存占用,减少事件注册,提高性能,比如在table上代理所有td的click事件就非常棒,可以实现当新增子元素时无需再次对其绑定。

eval是做什么的?

它的功能是把对应的字符串解析成JS代码并运行;
应该避免使用eval,不安全,非常耗性能(2次,一次解析成js语句,一次执行)。
由JSON字符串转换为JSON对象的时候可以用eval,var obj =eval(’(’+ str +’)’);

null,undefined 的区别?

null 表示一个对象是“没有值”的值,也就是值为“空”;
undefined 表示一个变量声明了没有初始化(赋值);
undefined不是一个有效的JSON,而null是;
undefined的类型(typeof)是undefined;
null的类型(typeof)是object;
在验证null时,一定要使用=== ,因为 == 无法分别 null 和 undefined

事件模型

  • W3C定义事件发生的三个阶段:捕获阶段(capturing)、目标阶段(targeting)、冒泡阶段(bubbling)
  • 冒泡型事件:子级元素先触发,父级元素后触发
  • 捕获型事件:父级元素先触发,子级元素后触发
  • DOM事件流:同时支持两种事件模型:冒泡型事件和捕获型事件
  • 阻止冒泡:使用stopPropagation()方法
  • 阻止捕获:阻止事件的默认行为,使用preventDefault()方法

new操作符具体干了什么?

  • 创建一个新对象,并且this变量引用该对象,同时继承了该函数的原型
  • 属性和方法被加入到this引用的对象中
  • 新创建的对象由this所引用,并且最后隐式的返回this
    var obj = {};
    obj.proto = Base.prototype;
    Base.call(obj);

什么是闭包?说说你对闭包的理解?

  • 闭包就是能够读取其他函数内部变量的函数,创建闭包最常见的方式是在一个函数内创建另一个函数,通过另一个函数访问这个函数的内部变量。
  • 闭包的特性:
    函数内再嵌套函数
    内部函数可以引用外部函数的变量和参数
    参数和变量不会被垃圾回收机制回收
  • 闭包的最大用处有两个,一个是可以读取函数内部的变量,让这些变量始终保存在内存中。另一个用处是,封装对象的私有属性和私有方法。
  • 优点:1.变量长期驻扎在内存中;
    2.避免全局变量的污染;
    3.私有成员的存在;
  • 缺点:常驻内存会增大内存的使用量;使用不当会造成内存泄;详解:
    (1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
    (2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

Javascript中,有一个函数,执行时对象查找时,永远不会去查找原型,这个函数是?

hasOwnProperty
hasOwnProperty函数方法是返回一个布尔值,指出一个对象是否具有指定名称的属性。此方法无法检查该对象的原型链中是否具有该属性;该属性必须是对象本身的一个成员。
使用方法:object.hasOwnProperty(proName)

js延迟加载的方式有哪些?

defer和async、动态创建DOM方式(用的最多)、按需异步载入JS

Ajax 是什么? 如何创建一个Ajax?

ajax的全称:Asynchronous Javascript And XML,异步传输+js+xml。
所谓异步,在这里简单地解释就是:向服务器发送请求的时候,我们不必等待结果,而是可以同时做其他的事情,等到有了结果它自己会根据设定进行后续操作,与此同时,页面是不会发生整页刷新的,提高了用户体验。
(1)创建XMLHttpRequest对象,也就是创建一个异步调用对象
(2)创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息
(3)设置响应HTTP请求状态变化的函数
(4)发送HTTP请求
(5)获取异步调用返回的数据
(6)使用JavaScript和DOM实现局部刷新

同步和异步的区别?

同步:浏览器访问服务器请求,用户看得到页面刷新,重新发请求,等请求完,页面刷新,新内容出现,用户看到新内容,进行下一步操作。
异步:浏览器访问服务器请求,用户正常操作,浏览器后端进行请求。等请求完,页面不刷新,新内容也会出现,用户看到新内容。

如何解决跨域问题?

jsonp、 iframe、window.name、window.postMessage、服务器上设置代理页面

谈一谈你对ECMAScript6的了解?

ES6,是ECMAScript的第六次修订,于2015年完成,也称ES2015ES6是继ES5之后的一次改进,相对于ES5更加简洁,提高了开发效率ES6新增的一些特性:
1)let声明变量和const声明常量,两个都有块级作用域ES5中是没有块级作用域的,并且var有变量提升,在let中,使用的变量一定要进行声明
2)箭头函数ES6中的函数定义不再使用关键字function(),而是利用了()=>来进行定义
3)模板字符串模板字符串是增强版的字符串,用反引号(`)标识,可以当作普通字符串使用,也可以用来定义多行字符串
4)解构赋值ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值
5)for of循环for…of循环可以遍历数组、Set和Map结构、某些类似数组的对象、对象,以及字符串
6)import、export导入导出ES6标准中,Js原生支持模块(module)。将JS代码分割成不同功能的小块进行模块化,将不同功能的代码分别写在不同文件中,各模块只需导出公共接口部分,然后通过模块的导入的方式可以在其他地方使用
7)set数据结构Set数据结构,类似数组。所有的数据都是唯一的,没有重复的值。它本身是一个构造函数
8)… 展开运算符可以将数组或对象里面的值展开;还可以将多个值收集为一个变量
9)修饰器 @decorator是一个函数,用来修改类甚至于是方法的行为。修饰器本质就是编译时执行的函数
10)class 类的继承ES6中不再像ES5一样使用原型链实现继承,而是引入Class这个概念11)async、await使用 async/await, 搭配promise,可以通过编写形似同步的代码来处理异步流程, 提高代码的简洁性和可读性async 用于申明一个 function 是异步的,而 await 用于等待一个异步方法执行完成
12)promisePromise是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理、强大
13)SymbolSymbol是一种基本类型。Symbol 通过调用symbol函数产生,它接收一个可选的名字参数,该函数返回的symbol是唯一的
14)Proxy代理使用代理(Proxy)监听对象的操作,然后可以做一些相应事情

var、let、const之间的区别

var声明变量可以重复声明,而let不可以重复声明
var是不受限于块级的,而let是受限于块级
var会与window相映射(会挂一个属性),而let不与window相映射
var可以在声明的上面访问变量,而let有暂存死区,在声明的上面访问变量会报错
const声明之后必须赋值,否则会报错
const定义不可变的量,改变了就会报错
const和let一样不会与window相映射、支持块级作用域、在声明的上面访问变量会报错

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

(1)用了箭头函数,this就不是指向window,而是父级(指向是可变的)
(2)不能够使用arguments对象
(3)不能用作构造函数,这就是说不能够使用new命令,否则会抛出一个错误
(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数

ES6的模板字符串有哪些新特性?

基本的字符串格式化。
将表达式嵌入字符串中进行拼接。
用${}来界定在ES5时我们通过反斜杠()来做多行字符串或者字符串一行行拼接。
ES6反引号(``)就能解决类模板字符串的功能

介绍下 Set、Map的区别?

应用场景Set用于数据重组,Map用于数据储存
Set: 
(1)成员不能重复
(2)只有键值没有键名,类似数组
(3)可以遍历,方法有add, delete,has
Map:
(1)本质上是健值对的集合,类似集合
(2)可以遍历,可以跟各种数据格式转换

ECMAScript 6 怎么写 class ,为何会出现 class?

ES6的class可以看作是一个语法糖,它的绝大部分功能ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法

//定义类
class Point {
constructor(x,y) {
//构造方法
this.x = x; //this关键字代表实例对象
this.y = y;
} toString() {
return ‘(’ + this.x + ‘,’ + this.y + ‘)’;
}
}

说说你对promise的了解

  • promise是什么?
    主要用于异步计算
    可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
    可以在对象之间传递和操作promise,帮助我们处理队列
    promise对象用来进行延迟和异步计算
  • 三个状态:
    pending、fulfilled、reject
    两个过程:
    padding -> fulfilled、padding -> rejected当pending为rejectd时,会进入catch
  • promise的优缺点:
    优点:可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,promise对象提供统一的接口,使得控制异步操作更容易。
    缺点:首先,无法取消promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,promise内部抛出的错误,不会反应到外部。第三,当处于pending状态时,无法得知目前进展到哪一阶段。

Promise 中reject 和 catch 处理上有什么区别

reject 是用来抛出异常,catch 是用来处理异常
reject 是 Promise 的方法,而 catch 是 Promise 实例的方法
reject后的东西,一定会进入then中的第二个回调,如果then中没有写第二个回调,则进入catch
网络异常(比如断网),会直接进入catch而不会进入then的第二个回调

如何使用Set去重

let arr = [12,43,23,43,68,12];
let item = […new Set(arr)];
console.log(item);//[12, 43, 23, 68]

forEach、for in、for of三者区别

forEach更多的用来遍历数组
for in 一般常用来遍历对象或json
for of数组对象都可以遍历,遍历对象需要通过和Object.keys()
for in循环出的是key,for of循环出的是value

documen.write和 innerHTML的区别

document.write是直接写入到页面的内容流,如果在写之前没有调用document.open, 浏览器会自动调用open。每次写完关闭之后重新调用该函数,会导致页面被重写。
innerHTML则是DOM页面元素的一个属性,代表该元素的html内容。你可以精确到某一个具体的元素来进行更改。如果想修改document的内容,则需要修改document.documentElement.innerElement。
innerHTML很多情况下都优于document.write,其原因在于其允许更精确的控制要刷新页面的那一个部分。

DOM操作——怎样添加、移除、移动、复制、创建和查找节点?

(1)创建新节点
createDocumentFragment() //创建一个DOM片段
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点
(2)添加、移除、替换、插入
appendChild()
removeChild()
replaceChild()
insertBefore() //在已有的子节点前插入一个新的子节点
(3)查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值(IE容错能力较强,会得到一个数组,其中包括id等于name值的)
getElementById() //通过元素Id,唯一性

call()和apply()方法的区别

相同点:call()和apply()方法的相同点就是这两个方法的作用是一样的。都是在特定的作用域中调用函数,等于设置函数体内this对象的值,以扩充函数赖以运行的作用域。

不同点:接收参数的方式不同
apply()方法接收两个参数,一个是函数运行的作用域(this),另一个是参数数组。
call()方法不一定接受两个参数,第一个参数也是函数运行的作用域(this),但是传递给函数的参数必须列举出来。

数组和对象有哪些原生方法,列举一下?

Array.concat( ) 连接数组
Array.join( ) 将数组元素连接起来以构建一个字符串
Array.length 数组的大小
Array.pop( ) 删除并返回数组的最后一个元素
Array.push( ) 给数组添加元素
Array.reverse( ) 颠倒数组中元素的顺序
Array.shift( ) 将元素移出数组
Array.slice( ) 返回数组的一部分
Array.sort( ) 对数组元素进行排序
Array.splice( ) 插入、删除或替换数组的元素
Array.toLocaleString( ) 把数组转换成局部字符串
Array.toString( ) 将数组转换成一个字符串
Array.unshift( ) 在数组头部插入一个元素

Object.hasOwnProperty( ) 检查属性是否被继承
Object.isPrototypeOf( ) 一个对象是否是另一个对象的原型
Object.propertyIsEnumerable( ) 是否可以通过for/in循环看到属性
Object.toLocaleString( ) 返回对象的本地字符串表示
Object.toString( ) 定义一个对象的字符串表示
Object.valueOf( ) 指定对象的原始值

解释 JavaScript 中的作用域与变量声明提升?

我对作用域的理解是只会对某个范围产生作用,而不会对外产生影响的封闭空间。在这样的一些空间里,外部不能访问内部变量,但内部可以访问外部变量。
所有申明都会被提升到作用域的最顶上
同一个变量申明只进行一次,并且因此其他申明都会被忽略
函数声明的优先级优于变量申明,且函数声明会连带定义一起被提升

JavaScript 中如何检测一个变量是一个 String 类型?

三种方法(typeof、constructor、Object.prototype.toString.call())

如何判断 JS 变量的一个类型(至少三种方式)

typeof、instanceof、 constructor、 prototype

如何判断一个对象是否为数组

第一种方法:使用 instanceof 操作符。
第二种方法:使用 ECMAScript 5 新增的 Array.isArray()方法。
第三种方法:使用使用 Object.prototype 上的原生 toString()方法判断。

defer、async的区别

  • defer 并行加载JS文件,会按照页面上script的标签的顺序执行
  • async 并行加载JS文件,下载完成立即执行,不会按照页面上script标签的顺序执行

JS 哪些操作会造成内存泄露

  • 意外的全局变量引起的内存泄露
  • 闭包引起的内存泄露
  • 没有清理的 DOM 元素引用
  • 被遗忘的定时器或者回调

Split() Join()的区别

  • join():用于把数组中的所有元素通过指定的分隔符进行分隔放入一个字符串
  • split():用于把一个字符串通过指定的分隔符进行分隔成数组

attribute和prototype的区别是什么?

  • attribute是DOM元素在文档中作为HTML标签拥有的属性;
  • prototype是DOM元素在JS中作为对象拥有的属性;
  • 对于HTML的标准属性来说,attribute和prototype是同步的,会自动更新的
  • 但对于自定义的属性来说,它们是不同步的

map和forEach的区别?

  • forEach方法,是最基本的方法,就是遍历与循环,默认有三个传参:item、index、当前遍历数组array
  • map方法,基本用法与forEach一致,但是不同的,它会返回一个新数组,所以在callback需要有return值,如果没有,会返回undefined

document.write和innerHTML的区别?

  • document.write是直接写入到页面的内容流,如果在写之前没有调用document.open, 浏览器会自动调用open。每次写完关闭之后重新调用该函数,会导致页面被重写。
  • innerHTML则是DOM页面元素的一个属性,代表该元素的html内容。你可以精确到某一个具体的元素来进行更改。如果想修改document的内容,则需要修改document.documentElement.innerElement。
  • 两者都可动态包含外部资源如JavaScript文件,通过document.write插入元素并不会执行其中的脚本
  • innerHTML很多情况下都优于document.write,其原因在于其允许更精确的控制要刷新页面的那一个部分。

什么是 event.target ?什么是event.currentTarget?

  • event.target是发生事件的元素或触发事件的元素。
  • event.currentTarget是我们在其上显式附加事件处理程序的元素。

== 和 === 有什么区别?

==用于一般比较,===用于严格比较,==在比较的时候可以转换数据类型,===严格比较,只要类型不匹配就返回flase。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值