前端面试之路二(javaScript基础整理)

1、变量类型和计算

JS中使用typeof能获得哪些类型

变量类型
  • 值类型:变量自己就是含有赋予给它的数值的,它的变量自己及保存的数据都存储在栈的内存块当中
  • 引用类型:引用类型固然是分配到堆上的对象或者数据变量,根据官方一点的解释就是引用类型的变量只包括对其所表示的数据引用javascript

    • 对象、数组、函数
    • 无限扩展属性,可能出现内存占用比较大的状况
typeof abc      //"undefined"
typeof NaN      //"number"
typeof null     //"object"
typeof console.log //"function"

typeof只能区分值类型,对引用类型无能为力,只能区分函数function<br/>
NaN表示特殊的非数字值,null是空指针,并无指向任何一个地址<br/>
typeof能区分的五种基本类型:stringbooleannumberundefinedsymbol和函数functionhtml

变量计算

可能发生强制类型转换的状况:
  • 字符串拼接
  • == 运算符
100  ==  '100'  //true
0    ==  ""     //true
null ==  undefined  //true
  • if语句
var c = '';
    if(c){
        //....
    }
  • 逻辑运算
console.log(10 && 0);       //0
 console.log('' || 'abc');   //'abc'
 console.log(!window.abc);   //true
 
 
 //判断一个变量会被当作true仍是false
 双非判断
 var a = 100;
 console.log(!!a);

在js逻辑运算中,0、NaN、""、null、false、undefined都会判为false,其余都为true前端

var add_level = (add_step == 5 && 1)||(add_step == 10 && 2)||(add_step == 12 && 4)||(add_step==15 && 5 )|| 0;
var add_level = {'5':1,'10':2,'15':5,'12':4}[add_step]||0; //更精简

什么时候使用 === 什么时候使用 ==

if(obj.a == null){
    //这里至关于obj.a === null || obj.a === undefined,简写
    //这是jquery源码中推荐的写法,除此以外其余全用 ===
    //主要是用于判断这个属性是否存在
}
//判断函数参数是否存在
function (a,b){
    if(a == null){
        ...
    }
}
//这种写法不能用
 if(xxx == null){
     //可能会报错,这个参数未定义  not defined
 }

JS变量按照存储方式区分为哪些类型,并描述其特色

如何理解json

  • JSON是一个JS内置对象,经常使用两个API
JSON.stringify({a:10,b:20})
 JSON.parse('{"a":10,"b":20}')
  • 同时也是一种数据格式

2、原型和原型链

原型规则

  • 全部的引用类型(数组、函数、对象)都具备对象特性,便可自由扩展属性】
  • 全部的引用类型(数组、对象、函数)有一个__proto__ 属性,属性值是一个普通的对象
  • 全部的函数都有一个prototype属性,属性值也是一个普通的对象
  • 全部的引用类型(数组、对象、函数),__proto__属性指向它的构造函数的prototype属性
  • 当试图获得一个对象的某个属性时,若是这个对象自己没有这个属性,那么回去他的__proto__(即它的构造函数的prototype中寻找)

原型链

instanceof

instanceof:用于判断引用类型属于哪一个构造函数的方法

f instanceof Foo的判断逻辑是:java

  • f的__proto__一层一层往上,可否对应到Foo.prototype
  • 再试着判断f instance Object

如何准确判断一个变量是不是数组类型

var arr = []
arr instanceOf Array //true
typeof arr //object,typeof是没法判断是不是数组的node

通用判断方法:Object.prototype.toString.call(arr) === "[object Array]"jquery

写一个原型链继承的例子

function Elem (id){ 
    this.elem = document.getElementById(id);
}
Elem.prototype.html = function(val){ 
    var elem = this.elem;
    if(val){ 
        elem.innerHtml = val;
        return this;   //链式操做
    }else{ 
        return elem.innerHtml; 
    }
} 

Elem.prototype.on = function(type,fn){
    var elem = this.elem
    elem.addEventListener(type,fn)
}

var div1 = new Elem('content_wrapper')
//div1.html('<p>ds<p>')
//div1.on('click',function(){
//    alert('clicked')
//    }
//)
div1.html('<p>放大放大放大发范德萨大点的我请萨</p>').on('click',function(){
    alert('clicked');
}).html('<p>javascript</p>')

描述建立一个对象的过程

  • 新生成了一个对象
  • 连接到原型
  • 绑定 this
  • 返回新对象
function create() {
    let obj = new Object()
    let Con = [].shift.call(arguments)
    obj.__proto__ = Con.prototype
    let result = Con.apply(obj, arguments)
    return typeof result === 'object' ? result : obj
}

zepto源码中如何使用原型链

3、做用域和闭包

题目ios

  • 说一下对变量提高的理解
  • 说明this几种不一样的使用场景
  • 建立10个 < a>标签,点击的时候弹出对应的序号
  • 如何理解做用域
  • 实际开发中闭包的应用

执行上下文

  • 范围:一段<script>或者一个函数
  • 全局:变量定义、函数声明、一段<script>
  • 函数:变量定义、函数声明、this、arguments
console.log(a)    //undefined
var a = 100
fn('zhangsan')    //'zhangsan' 20
function fn(name){
    age = 20
    console.log(name,age)
    var age
}
  • 函数声明会被提出来,函数表达式会和变量同样,以undefined占位
  • 在函数执行以前,变量定义、函数声明、thisarguments都要先提取出来

函数声明函数表达式的区别

fn()                    //不会报错
function fn(){
    //声明
}
fn()                    //Uncaught TypeError:fn1 is not a function 
var a = function(){
    //表达式
}
  • 变量提高: var a ; undefined,并不知道是一个函数
  • 函数提高: 把函数声明提早
fn('zhangsan')

function fn(name){
    //函数
    console.log(this)
    console.log(arguments)

    age = 20
    console.log(name,age)
    var age
    
    bar(100)
    function bar(num){
        console.log(num)
    }
}

说明this几种不一样的使用场景

  • 做为构造函数执行
  • 做为对象属性执行
  • 做为普通函数执行(window)
  • callapplybind
var a = {
    name : 'A',
    fn:function(){
        console.log(this.name)
    }
}

a.fn()                  //this  === a
a.fn.call({name:'B'})   //this  === {name:'B'}
var fn1 = a.fn
fn1()                   //this === window

this要在执行的时候才能确认值面试

做用域

没有块级做用域
if(true){
    var name = 'zhangsan'
}
console.log(name)
函数做用域和全局做用域
var a = 100
function fn(){
    var a = 200
    console.log('fn',a)
}

console.log('global',a)

fn()

做用域链

如何理解做用域:
  • 自由变量
  • 做用域链,即自由变量的查找
  • 闭包的两个场景
var a = 100
function fn(){
    var b = 200
    //当前做用域没有定义的变量,即“自由变量”
    console.log(a)
    console.log(b)
}
fn()

自由变量做用域链,一直往父级做用域找,一直找到全局做用域ajax

var a = 100
function F1(){
    var b = 200
    function F2(){
        var c = 300
        console.log(a)   //a是自由变量
        console.log(b)     //b是自由变量
        console.log(c)
    }
    F2()
}
F1()

闭包

做用域是定义时的做用域,而不是执行时的做用域chrome

闭包的使用场景:

函数做为返回值

function F1(){
    var a = 100
    //返回一个函数(函数做为返回值)
    return function(){
        console.log(a)
    }
}

var f1 = F1()
var a = 200
f1()
函数做为参数传递
function F1(){
    var a = 100
    return function(){
        console.log(a)   //自由变量,父做用域寻找
    }
}

var f1 = F1()

function F2(fn){
    var a = 200
    fn()
}

F2(f1)

面试题

题目一、说一下对变量提高的理解

在某一做用域中,声明变量的语句会默认解析为在该做用域的最开始就已经声明了

题目二、说明this几种不一样的使用场景

https://blog.csdn.net/w_q_102...

题目三、建立10个 < a>标签,点击的时候弹出对应的序号

错误写法
var i,a
for(i = 0;i<10;i++){
    a = document.createElement('a')
    a.innerHTMl = i + '<br>'
    a.addEventListener('click',function(e){
        e.preentDefault()
        alert(i)
    })
    document.body.appendChild(a)
}
正确写法
var i,a
for(i = 0;i < 10;i++){
    (function(i){
        var a = document.createElement('a')
        a.innerHTML = i + '<br>'
        a.addEventListener('click',function(e){
            e.preventDefault()
            alert(i)        
        })
        document.body.appendChild(a)
    })(i)
}

题目四、如何理解做用域

  • 自由变量
  • 做用域链,即自由变量的查找
  • 闭包的两个场景

题目五、实际开发中闭包的应用

//闭包实际应用中主要用于封装变量,收敛权限

function isFirstLoad(){ 
    var _list = []; 
    return function(id){
        if(_list.indexOf(id) >= 0){
            return false; 
        }else{ 
            _list.push(id);
            return true;
        } 
    }}
    var firstLoad = isFirstLoad();
    firstLoad(10);

4、异步和单线程

题目:

  • 同步和异步的区别是什么?分别举一个同步和异步的例子
  • 一个关于setTimeout的笔试题
  • 前端使用异步的场景有哪些

知识点

  • 什么是异步(对比同步)
  • 前端使用异步的场景
  • 异步和单线程

什么是异步

是否阻塞程序的运行

什么时候须要异步

在可能发生等待的状况
  • 定时任务:setTimeout,setTimeInterval
  • 网络请求:ajax请求,动态<img>加载
  • 事件绑定

等待过程当中不能像alert同样阻塞程序运行

所以全部的“等待的状况”都须要异步

异步和单线程

console.log(100)
setTimeout(function(){
    console.log(200)
},1000)
console.log(300)
  • 执行第一行,打印100
  • 执行setTimeout后,传入setTimeout的函数会被暂存起来,不会当即执行(单线程特色,不能同时干两件事)
  • 执行最后一行,打印300
  • 待全部程序执行完,处于空闲状态时,会立马看有没有暂存起来的要执行
  • 发现暂存起来的setTimeout中的函数无需等待时间,就当即来过来执行

面试题

笔试题1: 同步和异步的区别是什么?分别举一个同步和异步的例子

同步会阻塞代码执行,而异步不会

笔试题2:一个关于setTimeout的笔试题

console.log(1)

setTimeout(function(){
    console.log(2)
},0)

console.log(3)

setTimeout(function(){
    console.log(4)
},1000)

console.log(5)

笔试题3:前端使用异步的场景有哪些

须要等待,由于js是单线程语言

5、常见对象

题目

  • 获取2017-06-10格式的日期
  • 获取随机数,要求是长度一直的字符串格式
  • 写一个能遍历对象和数组的通用forEach函数

Date

Date.now() //获取当前时间毫秒数
  
var dt = new Date()
dt.getTime()          //获取毫秒数
dt.getFullYear()      //年
dt.getMonth()        //月(0-11)
dt.getDate()        //日(0-31)
dt.getHours()        //小时(0-23)
dt.getMinutes()        //分钟(0-59)
dt.getSeconds()        //秒(0-59)

Math

Math.random():能够用来清除缓存

Array

  • forEach 遍历全部数据
  • every 判断全部元素是否都符合条件
  • some 判断是否有至少一个元素符合条件
  • sort 排序
  • map 对元素从新组装,生成新数组>- 过滤符合条件的元素
array.forEach
arr.forEach( function(item,index){ 
    console.log(index,item); 
});
array.every
var arr = [1,2,3,4,5];
var result = arr.every(function(index,item){
//用来判断全部的数组元素,都知足一个条件 
    if(item<6) 
        return true
});
    console.log(result);
array.some
var result = arr.some(function(index,item){ 
    if(item<5) 
        return true;
}); 
console.log(result);
arry.sort
var arr2 = arr.sort(function(a,b){ 
    //从小到大排序 return a-b; 
    //从大到小排序 
    //return b-a;
})
array.map
arr.map(function(item,index){
    return '<br>'+index+':'+item+'<br>'
})
array.filter
var arr2 = arr.filter(function (item,index){ 
    //经过某一个条件过滤数组 
    if(item >= 2) 
        return true
})

对象API

var obj = {
    x:100,
    y:200,
    z:300
}

var key

for(key in obj){
    if(obj.hasOwnProperty(key)){
        console.log(key,obj[key])
    }
}

面试题

解答1:获取2016-06-10格式的日期

function formatDate(dt){
    if(!dt){
        dt = new Date()
    }

    var year  = dt.getFullYear()
    var month = dt.getMonth() + 1
    var date  = dt.getDate()

    if(month < 10){
        //强制类型转换
        month = '0' + month 
    }

    if(date < 10){
        //强制类型转换
        date = '0' + date
    }
    //强制类型转换
    return year + '-' + month + '-' + date
}

var dt = new Date()
var formatDate = formatDate(dt)
console.log(formatDate)

解答2:获取随机数,要求是长度一致的字符串格式

var random = Math.random() + '0000000000';
var random = random.slice(0,10);

解答3:写一个能遍历对象和数组的通用forEach函数

function forEach(obj,fn){
    var key
    if(obj instanceof Array){
        //准备判断是否是数组
        obj.forEach(function(item,index){
            fn(index,item)
        })
    }else{
        //不是数组就是对象
        for(key in obj){
            fn(key,obj[k])
        }
    }
}

5、JS-Web-API:

知识点:

  • js基础知识:ECMA262标准
  • JS-Web-API:W3C标准

W3C标准中关于JS的规定有:

  • DOM操做
  • BOM操做
  • 事件绑定
  • ajax请求(包括http协议)
  • 存储

DOM操做

DOM的本质
DocumentObjectModel
浏览器把拿到的html代码,结构化一个浏览器可以识别而且js可操做的一个模型而已

DOM的节点操做

  • 获取DOM节点
  • Attribute 和 properity
  • attribute:是HTML标签上的某个属性,如id、class、value等以及自定义属性,它的值只能是字符串,关于这个属性一共有三个相关的方法,setAttribute、getAttribute、removeAttribute;

注意:在使用setAttribute的时候,该函数必定接收两个参数,setAttribute(attributeName,value),不管value的值是什么类型都会编译为字符串类型。在html标签中添加属性,本质上是跟在标签里面写属性时同样的,因此属性值最终都会编译为字符串类型。

  • property:是js获取的DOM对象上的属性值,好比a,你能够将它看做为一个基本的js对象。这个节点包括不少property,好比value,className以及一些方法onclik等方法。

一个js对象有不少property,该集合名字为properties,properties里面有其余property以及attributies,attributies里面有不少attribute。
而经常使用的attribute,id、class、name等通常都会做为property附加到js对象上,能够和property同样取值、赋值

DOM结构操做

面试题1:DOM是那种基本的数据结构?

面试题2:DOM操做的经常使用API有哪些?

  • 获取DOM节点,以及节点的propertyAttribute
  • 获取父节点,获取子节点
  • 新增节点,删除节点

面试题3:DOM节点的attr和property有何区别

property只是一个JS对象的属性的修改

Attribute是对html标签属性的修改

BOM操做

问题:

  • 如何检测浏览器的类型
  • 拆解URL各部分

知识点

  • navigator
  • screen
  • location
  • history

navigator & screen

//navigator
var ua = navigator.userAgent
var isChrome = ua.indexOf('chrome')
console.log(isChrome)

//screen
console.log(screen.width)
console.log(screen.height)

//location
console.log(location.href)
console.log(location.protocol)
console.log(location.pathname)
console.log(location.search)    //?以后的参数
console.log(location.hash)      //#号以后

//history
history.back()          
history.forward()

6、事件

题目:

  • 编写一个通用的事件监听函数
  • 描述时间冒泡流程
  • 对于一个无限下拉加载图片的页面,如何给每一个图片绑定事件

知识点:

  • 通用事件绑定
  • 事件冒泡
  • 代理

知识点

通用事件绑定

var btn = document.getElementById('btn1')
btn.addEventListener('click', function(event) {
    console.log('clicked')
})

function bindEvent(elem, type, fn) {
    elem.addEventListener(type, fn)
}

var a = document.getElementById('link1')
bindEvent(a, 'click', function(e) {
    e.preventDefault(); //阻止默认行为
    alert('clicked')
})
关于IE低版本的兼容性
  • IE低版本使用attachEvent绑定事件,和W3C标准不同
  • IE低版本使用量已很是少,不少网站早已不支持
  • 建议对IE低版本的兼容性:了解便可,无须深究
  • 若是遇到对IE低版本要求苛刻的面试,果断放弃

事件冒泡

e.stopPropatation() //取消冒泡

代理

<div id="div1">
    <a href = "#">a1</a>
    <a href = "#">a2</a>
    <a href = "#">a3</a>
    <a href = "#">a4</a>
    <!--会随时新增更多 a 标签-->
</div>


var div1 = document.getElementById('div1')
div1.addEventListener('click',function(e){
    var target = e.target
    if(target.nodeName === 'A'){
        alert(target.innerHTMl)
    }
})

完整写法

function bindEvent(elem, type, selector, fn) {
    if (fn == null) {
        fn = selector
        selector = null
    }

    elem.addEventListener(type, function(e) {
        var target
        if (selector) {
            target = e.target
            if (target.matches(selector)) {
                fn.call(target, e)
            }
        } else {
            fn(e)
        }
    })
}

//使用代理
var div1 = document.getElementById('div1')
bindEvent(div1, 'click', 'a', function(e) {
    console.log(this.innerHTML)
})

//不使用代理
var a = document.getElementById('a1')
bindEvent(div1, 'click', function(e) {
    console.log(a.innerHTML)
})

面试题

面试题1:编写一个通用的事件监听函数

面试题2:描述事件冒泡流程

  • DOM树形结构
  • 事件冒泡
  • 组织冒泡
  • 冒泡的应用

面试题3:对于一个无限下拉加载图片的页面,如何给每一个图片绑定事件

  • 使用代理
  • 知道代理的两个优势

7、Ajax

题目:

  • 手动写一个ajax,不依赖第三方库
  • 跨域的几种实现(原理)

知识点:

  • xmlHttpRequest
  • 状态码说明
  • 跨域

XMLHttpRequest

var xhr = new XMLHttpRequest()

xhr.open("GET","/api",false)

xhr.onreadystatechange = function(){
    //这里的函数异步执行,可参考以前JS基础中的异步模块
    if(xhr.readyState == 4){
        if(xhr.status == 200){
            alert(xhr.responseText)
        }
    }
}

xhr.send(null)
IE兼容性问题
  • IE低版本使用ActiveXObject,和W3C标准不同
  • IE低版本使用量已经很是少,不少网站早已不支持
  • 建议对IE低版本的兼容性:了解便可,无需深究
  • 若是遇到对IE低版本要求苛刻的面试,果断放弃

.

状态码说明
  • 0 - (未初始化)     还没调用send()方法
  • 1 - (载入)            已调send() 方法,正在发送请求
  • 2 - (载入完成)     send()方法执行完成,已经接收到所有相应内容
  • 3 - (交互)            正在解析响应内容
  • 4 - (完成)            响应内容解析完成,能够在客户端调用了

.

status说明

  • 2XX - 表示成功处理请求。如200
  • 3XX - 须要重定向,浏览器直接跳转
  • 4XX - 客户端请求错误,如404
  • 5XX - 服务器端错误

跨域

什么是跨域
  • 浏览器有同源策略,不容许ajax访问其余域的接口
  • 跨域条件:协议、域名、端口,有一个不一样就算跨域

 

能够跨域的三个标签
  • <img src=''>
  • <script src=''>
  • <link href=''>

 

三个标签的场景
  • <img>用于打点统计,统计网站多是其余域(并且没有任何兼容性问题)
  • <link> <script>可使用CDN,CDN也是其余域
  • <script>能够用于JSONP

 

跨越注意的问题
  • 全部的跨域请求都必须通过信息提供方容许
  • 若是未经容许便可获取,那是浏览器同源策略出现漏洞

 

JSONP实现原理
  • 加载 http://coding.xxx.com/classin...
  • 不必定服务器端真正有一个classindex.html文件
  • 服务器能够根据请求,动态生成一个文件,返回
  • 通理于<script src="http://coding.xxxxx.com/api.js">
//例如你的网站要跨域访问xx网的一个接口
//给你一个地址 http://coding.xxxx.com/api.js
//返回内容格式 callback({x:100,y:200})

<script>
window.callback = function(data){
    //这是咱们跨域获得信息
    console.log(data)
}
</script>
<script src="http://coding.m.xxxxx.com/api.js"></script>
服务器端设置http header

cookiesessionStoragelocalStorage的区别

  • 容量
  • 是否会携带到ajax中
  • API易用性
ios safari隐藏模式下,localStorage.getItem会报错,建议统一用try-catch封装



面试全家桶

HTML+CSS 面试整理                                --------------------------------> 点这里

前端高级面试整理(三大框架等深刻知识) --------------------------------> 点这里

javascript性能优化                                      --------------------------------> 点这里

javascript设计模式                                      --------------------------------> 点这里

HTTP相关面试                                            -------------------------------->点这里

相关文章
相关标签/搜索