当前位置: 首页 > news >正文

面试总结JavaScript篇

此文主旨是记录面试中遇到的面试题,包括js中常见,易错,重要知识点

window.onload和$(document).ready()的区别

window.onload是在页面中包含图片在内的所有元素全部加载完成再执行;
$(document).ready()是DOM树加载完成之后执行,不包含图片,其他媒体文件;
因此$(document).ready()快于window.onload执行;

数组去重

const arr = ['a','bb','22','a','yuci','haha','22']; 

1.es6数据结构Set

let unique = new Set(arr);  
console.log(Array.from(unique)); 

2.使用push()

let arr2 = [];  
for(let i = 0; i < arr.length; i++) {  
    if(arr2.indexOf(arr[i]) == -1) { //不包含某个值则返回-1  
        arr2.push(arr[i]);  
    }  
}  
console.log(arr2); 
//如果当前数组的第i项在当前数组中第一次出现的位置不是i,那么表示第i项是重复的,忽略掉。否则存入结果数组  
let arr3 = [arr[0]];  
for(let i = 1; i < arr.length; i++) {  
    if(arr.indexOf(arr[i]) == i) {  
        arr3.push(arr[i]);  
    }  
}  
console.log(arr3);  

3.排序去除相邻重复元素

let arrSort = arr.sort();  
let arr4 = [];  
for(let i = 0; i< arrSort.length; i++) {  
    if(arrSort[i] != arrSort[i+1]) {  
        arr4.push(arrSort[i]);  
    }  
}  
console.log(arr4);  

4.使用splice()

let len = arr.length;  
for(let i = 0; i < len; i++) {  
    for(let j = i + 1; j < len; j++) {  
        if(arr[i] === arr[j]) {  
            arr.splice(i,1);  
            len--;  
            j--;  
        }  
    }  
}  
console.log(arr); 

事件委托

得益于事件冒泡,当多个元素有相同的事件,将事件绑定在父元素

var oUl = document.getElementById('oul');  
oUl.addEventListener('click', function(e) {  
    var e = e||window.event;  
    var tar = e.target;  
    if(tar.nodeName === 'LI') {  
        alert(tar.innerHTML);  
    }  
}) 

更详细请看:事件委托

判断变量类型

  • typeof()用于判断简单数据;
  • 判断一个变量是对象还是数组使用instanceof,constructor或Object.prototype.toString.call();

更详细请看:判断数据类型

同步和异步(简要阐述)

同步:由于js单线程,同步任务都在主线程上排队执行,前面任务没执行完成,后面的任务会一直等待;

异步:不进入主线程,进入任务队列,等待主线程任务执行完成,开始执行。最基础的异步操作setTimeout和setInterval,等待主线程任务执行完,在开始执行里面的函数;

更详细请看:js运行机制

返回false的几种情况

false,null,0,“”,undefined,NaN

js类型值的区别

存储地:

简单数据类型:存储在栈中;

引用数据类型:存储在堆中,在栈中存储了指针,指向存储在堆中的地址,解释器会先检索在栈中的地址,从堆中获得实体;

大小:

简单数据类型:大小固定,占用空间小,频繁使用,所以存储在栈中;

引用数据类型:大小不固定,占用空间大;

闭包

何为闭包:有权访问另一个作用域中变量的函数

闭包特性:可实现函数外访问函数内变量,外层变量可以不被垃圾回收机制回收

为什么?怎么解决?

for(var i = 0; i < 10; i++) {  
    setTimeout(function() {  
        console.log(i);    
    }, 1000);  
}  

输出结果都为10,因为for()循环过程中每次传值,匿名函数并没有执行,相当于执行10次function(){console.log(i);},循环结束i变为10,所以输出全部为10;

使用闭包,自执行匿名函数包裹:

for(var i = 0; i < 10; i++) {  
    (function(j) {  
        setTimeout(function() {  
            console.log(j);    
        }, 1000);  
    })(i);  
} 

外部匿名函数立即执行,把 i 作为参数,赋值给 j ,因为是立即执行,所以每次循环输出不同值。

引用外层变量不被回收,会相比其他函数占用更高内存,使用不当容易造成内存泄漏。

this的指向

全局范围:指向window(严格模式下不存在全局变量,指向undefined);

普通函数调用:指向window;

对象方法调用:指向最后调用它的对象;

构造函数调用:指向new出来的对象;

显示设置this:call,apply方法显示将this指向第一个参数指明的对象

new具体做了些什么

创建一个新对象foo;

并将它的__proto__指向其构造函数的prototype,foo.__proto__ = Foo.prototype;

动态将this指向新对象,Foo.apply(foo,arguments);

执行函数体中的代码;

放回新对象foo;

原型和原型链

创建一个函数就会为其创建一个prototype属性,指向这个函数的原型对象,原型对象会自动获得constructor属性,指向prototype属性所在函数。

Function.prototype.a = "a";    
Object.prototype.b = "b";    
function Person(){}    
console.log(Person);    //function Person()    
let p = new Person();    
console.log(p);         //Person {} 对象    
console.log(p.a);       //undefined    
console.log(p.b);       //b 
p.__proto__ === Person.prototype;Person.prototype.constructor === Person

当调用某种方法或查找某种属性时,首先会在自身调用和查找,如果自身并没有该属性或方法,则会去它的__proto__属性中调用查找,也就是它构造函数的prototype中调用查找,如果构造函数中也没有该属性方法,则会去构造函数的隐式原型中查找,一直到null,就这样形成原型链。

更多有关原型请看:原型和原型链

继承方式

原型链继承:

Child()的原型作为Parent()的实例来继承Parent()的方法属性

因为所有实例都继承原型方法属性,其中一个实例对原型属性值更改后,所有实例调用该属性的值全部更改

function Parent() {}  
Parent.prototype.parentSay = function() {  
    return 'i am parent';  
}  
function Child() {}  
Child.prototype.childSay = function() {  
    return 'i am child';  
}  
Child.prototype = new Parent();  
var par = new Parent();  
var kid = new Child();  
  
console.log(kid.parentSay());           //i am parent 

构造函数继承:

在子类的构造函数内部通过call或apply来调用父类构造函数

无法实现函数的复用

function People() {  
    this.name = ['zhangsan','lisi','wangwu'];  
}  
function Person() {  
    People.call(this);  
}  
var per1 = new Person();  
per1.name.push('zhanliu');  
console.log(per1.name);     //["zhangsan", "lisi", "wangwu", "zhanliu"]  
  
var per2 = new Person();  
console.log(per2.name);     //["zhangsan", "lisi", "wangwu"]  

组合继承:

将原型链继承和构造函数继承结合,最常用的继承模式

原型链继承共享的属性和方法,构造函数继承实例属性

function People(num) {  
    this.num = num;  
    this.name = ['zhangsan','lisi','wangwu'];  
}  
People.prototype.numCount = function() {  
    console.log(this.num);  
}  
function Person(num) {  
    People.call(this, num);  
}  
//继承方式  
Person.prototype = new People();  
Person.prototype.constructor = Person;  
  
var per1 = new Person(10);  
per1.name.push('zhaoliu');  
console.log(per1.name);     //["zhangsan", "lisi", "wangwu", "zhanliu"]  
per1.numCount();            //10  
  
var per2 = new Person(20);  
console.log(per2.name);     //["zhangsan", "lisi", "wangwu"]  
per2.numCount();            //20  

更多继承方式请看:继承方式

数组常用方法

改变原数组:

尾部删除pop(),尾部添加push(),头部删除shift(),头部添加unshift(),排序sort(),颠倒数组元素reverse(),删除或插入元素splice();

不会改变元素组:

合并数组concat(),拼接数组元素join(),截取元素slice(),indexOf(),lastIndexOf(),toString()

更详细数组方法总结请看:Array数组方法总结

数据存储

Cookie:用于客户端与服务端通信,也具有本地存储的功能

localStorage,sessionStorage:专门用于存储

区别:

大小:Cookie容量为4K,因为用于客户端与服务端通信,所有http都携带,如果太大会降低效率; localStorage,sessionStorage大小为5M。

失效时间:Cookie会在浏览器关闭时删除,除非主动设置删除时间;localStorage一直都在直到用户主动删除或清除浏览器缓存;sessionStorage在浏览器关闭时删除。

结束语:

如有错误,欢迎指正

相关文章:

  • Generic detail view PostDetailView must be called with either an object pk or a slug.解决
  • 高端家电“金选奖”名单揭晓,激起新消费主义浪潮
  • Python2与Python3的区别
  • 集群中用Memcached来实现session共享
  • AngularJs的表单验证
  • 如何查看linux中的ssh端口开启状态
  • Go 语言之 struct 结构体
  • 安卓设置背景图平铺,同时设置背景色
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • 为用户管理连接 Confluence 6 到 Jira 应用程序
  • 加密算法:DigestUtils与java MessageDigest
  • Spring Extensible XML
  • mooc-IDEA alter enter--008
  • 20172318 2017-2018-2 《程序设计与数据结构》第6周学习总结
  • 坚持不走寻常路 解读“锐捷式”创新的三个突破
  • 深入了解以太坊
  • [ 一起学React系列 -- 8 ] React中的文件上传
  • 2017届校招提前批面试回顾
  • Elasticsearch 参考指南(升级前重新索引)
  • HashMap剖析之内部结构
  • HTTP中GET与POST的区别 99%的错误认识
  • Linux快速复制或删除大量小文件
  • Phpstorm怎样批量删除空行?
  • Python3爬取英雄联盟英雄皮肤大图
  • vue.js框架原理浅析
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 用Python写一份独特的元宵节祝福
  • 在Unity中实现一个简单的消息管理器
  • 正则学习笔记
  • No resource identifier found for attribute,RxJava之zip操作符
  • 小白应该如何快速入门阿里云服务器,新手使用ECS的方法 ...
  • ​如何在iOS手机上查看应用日志
  • (ctrl.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“
  • (windows2012共享文件夹和防火墙设置
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (欧拉)openEuler系统添加网卡文件配置流程、(欧拉)openEuler系统手动配置ipv6地址流程、(欧拉)openEuler系统网络管理说明
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • (转)Oracle存储过程编写经验和优化措施
  • (转)setTimeout 和 setInterval 的区别
  • (转)大道至简,职场上做人做事做管理
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)
  • .NET Entity FrameWork 总结 ,在项目中用处个人感觉不大。适合初级用用,不涉及到与数据库通信。
  • .NET 事件模型教程(二)
  • .net 无限分类
  • .NET 应用架构指导 V2 学习笔记(一) 软件架构的关键原则
  • /etc/fstab 只读无法修改的解决办法
  • @Responsebody与@RequestBody
  • @SuppressWarnings注解
  • [ vulhub漏洞复现篇 ] ThinkPHP 5.0.23-Rce
  • [Big Data - Kafka] kafka学习笔记:知识点整理
  • [caffe(二)]Python加载训练caffe模型并进行测试1
  • [ERROR ImagePull]: failed to pull image k8s.gcr.io/kube-controller-manager失败
  • [JMS 3] ActiveMQ实现简单的helloworld