前端面试JS题目复习大纲

前端面试JS题目

JS

介绍js的基本数据类型。

Undefined、Null、Boolean、Number、String、

复杂数据类型:Object

 

介绍js有哪些内置对象?

Object 是 JavaScript 中所有对象的父对象
数据封装类对象:Object、Array、Boolean、Number 和 String
其他对象:Function、Arguments、Math、Date、RegExp、Error

 

说几条写JavaScript的基本规范?


1.不要在同一行声明多个变量。

2.请使用 ===/!==来比较true/false或者数值

3.使用对象字面量替代new Array这种形式

4.不要使用全局函数。

5.Switch语句必须带有default分支

6.函数不应该有时候有返回值,有时候没有返回值。

7.For循环必须使用大括号

8.If语句必须使用大括号

9.for-in循环中的变量 应该使用var关键字明确限定作用域,从而避免作用域污染。

 

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

每个对象都会在其内部初始化一个属性,就是prototype(原型),当我们访问一个对象的属性时,
如果这个对象内部不存在这个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype,
于是就这样一直找下去,也就是我们平时所说的原型链的概念。
关系:instance.constructor.prototype = instance.__proto__
 
特点:
JavaScript对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变。
 
 当我们需要一个属性的时,Javascript引擎会先看当前对象中是否有这个属性, 如果没有的话,
 就会查找他的Prototype对象是否有这个属性,如此递推下去,一直检索到 Object 内建对象。
    function Func(){}
    Func.prototype.name = "Sean";
    Func.prototype.getInfo = function() {
      return this.name;
    }
    var person = new Func();//现在可以参考var person = Object.create(oldObject);
    console.log(person.getInfo());//它拥有了Func的属性和方法
    //"Sean"
    console.log(Func.prototype);
    // Func { name="Sean", getInfo=function()}

 

JavaScript有几种类型的值?,你能画一下他们的内存图吗?

栈:原始数据类型(Undefined,Null,Boolean,Number、String) 
堆:引用数据类型(对象、数组和函数)
 
两种类型的区别是:存储位置不同;
原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;
引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定。如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体
 

如何实现数组的随机排序?

方法一: 
```javascript 



  var arr = [1,2,3,4,5,6,7,8,9,10]; 
     function randSort1(arr){ 
        for(var i = 0,len = arr.length;i < len; i++ ){ 
            var rand = parseInt(Math.random()*len); 
            var temp = arr[rand]; 
            arr[rand] = arr[i]; 
            arr[i] = temp; 
        }
         return arr;
     }
     console.log(randSort1(arr));
 
```
方法二:
```javascript
        var arr = [1,2,3,4,5,6,7,8,9,10];
        function randSort2(arr){
            var mixedArray = [];
            while(arr.length > 0){
                var randomIndex = parseInt(Math.random()*arr.length);
                mixedArray.push(arr[randomIndex]);
                arr.splice(randomIndex, 1);
            }
            return mixedArray;
        }
        console.log(randSort2(arr));
 
```
方法三:
```javascript
        var arr = [1,2,3,4,5,6,7,8,9,10];
        arr.sort(function(){
            return Math.random() - 0.5;
        })
        console.log(arr);
```                         

 

 

 

Javascript如何实现继承?

1、构造继承
2、原型继承
3、实例继承
4、拷贝继承
 
原型prototype机制或apply和call方法去实现较简单,建议使用构造函数与原型混合方式。
```javascript
        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作用链域?

全局函数无法查看局部函数的内部细节,但局部函数可以查看其上层的函数细节,直至全局细节。
当需要从局部函数查找某一属性或方法时,如果当前作用域没有找到,就会上溯到上层作用域查找,
直至全局函数,这种组织形式就是作用域链。

 

谈谈This对象的理解。

this总是指向函数的直接调用者(而非间接调用者);
如果有new关键字,this指向new出来的那个对象;
在事件中,this指向触发这个事件的对象,特殊的是,IE中的attachEvent中的this总是指向全局对象Window;
 

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;
Javascript将未赋值的变量默认值设为undefined;
Javascript从来不会将变量设为null。它是用来让程序员表明某个用var声明的变量时没有值的。
typeof undefined
    //"undefined"
    undefined :是一个表示"无"的原始值或者说表示"缺少值",就是此处应该有一个值,但是还没有定义。当尝试读取时会返回 undefined; 
    例如变量被声明了,但没有赋值时,就等于undefined
 
typeof null
    //"object"
    null : 是一个对象(空对象, 没有任何属性和方法);
    例如作为函数的参数,表示该函数的参数不是对象;
注意:
    在验证null时,一定要使用 === ,因为 == 无法分别 null 和 undefined
    null == undefined // true
    null === undefined // false

 

什么是闭包(closure),为什么要用它?

闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链域,将函数内部的变量和方法传递到外部。
闭包的特性:
1.函数内再嵌套函数
2.内部函数可以引用外层的参数和变量
3.参数和变量不会被垃圾回收机制回收
 
//li节点的onclick事件都能正确的弹出当前被点击的li索引
 <ul id="testUL">
    <li> index = 0</li>
    <li> index = 1</li>
    <li> index = 2</li>
    <li> index = 3</li>
</ul>
<script type="text/javascript">
    var nodes = document.getElementsByTagName("li");
    for(i = 0;i<nodes.length;i+= 1){
        nodes[i].onclick = (function(i){
                  return function() {
                     console.log(i);
                  } //不用闭包的话,值每次都是4
                })(i);
    }
</script>
执行say667()后,say667()闭包内部变量会存在,而闭包内部函数的内部变量不会存在
使得Javascript的垃圾回收机制GC不会收回say667()所占用的资源
因为say667()的内部函数的执行需要依赖say667()中的变量
这是对闭包作用的非常直白的描述
  function say667() {
    // Local variable that ends up within closure
    var num = 666;
    var sayAlert = function() {
        alert(num);
    }
    num++;
    return sayAlert;
}
 var sayAlert = say667();
 sayAlert()//执行结果应该弹出的667

 

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

use strict是一种ECMAscript 5 添加的(严格)运行模式,这种模式使得 Javascript 在更严格的条件下运行,
使JS编码更加规范化的模式,消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为。
默认支持的糟糕特性都会被禁用,比如不能用with,也不能在意外的情况下给全局变量赋值;
全局变量的显示声明,函数必须声明在顶层,不允许在非函数代码块内声明函数,arguments.callee也不允许使用;
消除代码运行的一些不安全之处,保证代码运行的安全,限制函数中的arguments修改,严格模式下的eval函数的行为和非严格模式的也不相同;
提高编译器效率,增加运行速度;
为未来新版本的Javascript标准化做铺垫。

 

new操作符具体干了什么呢?

1、创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
2、属性和方法被加入到 this 引用的对象中。
3、新创建的对象由 this 所引用,并且最后隐式的返回 this 
 

JSON 的了解?

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。
它是基于JavaScript的一个子集。数据格式简单, 易于读写, 占用带宽小
如:{"age":"12", "name":"back"}
JSON字符串转换为JSON对象:
var obj =eval('('+ str +')');
var obj = str.parseJSON();
var obj = JSON.parse(str);
JSON对象转换为JSON字符串:
var last=obj.toJSONString();
var last=JSON.stringify(obj);
 

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

ajax的全称:Asynchronous Javascript And XML。
异步传输+js+xml。
所谓异步,在这里简单地解释就是:向服务器发送请求的时候,我们不必等待结果,而是可以同时做其他的事情,等到有了结果它自己会根据设定进行后续操作,与此同时,页面是不会发生整页刷新的,提高了用户体验。
 
(1)创建XMLHttpRequest对象,也就是创建一个异步调用对象

(2)创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息

(3)设置响应HTTP请求状态变化的函数

(4)发送HTTP请求

(5)获取异步调用返回的数据

(6)使用JavaScript和DOM实现局部刷新

 

Ajax 解决浏览器缓存问题?

1、在ajax发送请求前加上 anyAjaxObj.setRequestHeader("If-Modified-Since","0")。
2、在ajax发送请求前加上 anyAjaxObj.setRequestHeader("Cache-Control","no-cache")。
3、在URL后面加上一个随机数: "fresh=" + Math.random();。
4、在URL后面加上时间搓:"nowtime=" + new Date().getTime();
5、如果是使用jQuery,直接这样就可以了 $.ajaxSetup({cache:false})。这样页面的所有ajax都会执行这条语句就是不需要保存缓存记录

 

同步和异步的区别?

同步的概念应该是来自于OS中关于同步的概念:不同进程为协同完成某项工作而在先后次序上调整(通过阻塞,唤醒等方式).同步强调的是顺序性.谁先谁后.异步则不存在这种顺序性.
同步:浏览器访问服务器请求,用户看得到页面刷新,重新发请求,等请求完,页面刷新,新内容出现,用户看到新内容,进行下一步操作。
异步:浏览器访问服务器请求,用户正常操作,浏览器后端进行请求。等请求完,页面不刷新,新内容也会出现,用户看到新内容。
 

如何解决跨域问题?

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

 

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

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

JavaScript 的 typeof 返回哪些数据类型?

typeof 返回七种可能的值:“number”、“string”、“boolean”、“object”、"symbol"、“function”和“undefined”。

 

请写出以下运算结果:

alert(typeof null);  // object
alert(typeof undefined);  // undefined
alert(typeof NaN);  // number
alert(NaN == undefined);  // false
alert(NaN == NaN);  // false
var str = "123abc";
alert(typeof str++);  // number
alert(str);  // NaN
 

例举至少 3 种强制类型转换和 2 种隐式类型转换?

1. 强制类型转换: 明确调用内置函数,强制把一种类型的值转换为另一种类型。强制类型转换主要有:BooleanNumberStringparseIntparseFloat
 
2. 隐式类型转换: 在使用算术运算符时,运算符两边的数据类型可以是任意的,比如,一个字符串可以和数字相加。之所以不同的数据类型之间可以做运算,是因为 JavaScript 引擎在运算之前会悄悄的把他们进行了隐式类型转换。隐式类型转换主要有:+、–、==!

 

BOM 对象有哪些,列举 window 对象?

  • window 对象,是 JS 的最顶层对象,其他的 BOM 对象都是 window 对象的属性;
  • location 对象,浏览器当前URL信息;
  • navigator 对象,浏览器本身信息;
  • screen 对象,客户端屏幕信息;
  • history 对象,浏览器访问历史信息;

HTTP 状态消息 200 302 304 403 404 500 分别表示什么?

  • 200:请求已成功,请求所希望的响应头或数据体将随此响应返回。
  • 302:请求的资源临时从不同的 URI 响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在 Cache-Control Expires 中进行了指定的情况下,这个响应才是可缓存的。
  • 304:如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码。304 响应禁止包含消息体,因此始终以消息头后的第一个空行结尾。
  • 403:服务器已经理解请求,但是拒绝执行它。
  • 404:请求失败,请求所希望得到的资源未被在服务器上发现。
  • 500:服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器端的源代码出现错误时出现。

GET和POST的区别,何时使用POST?

GET:一般用于查询数据,使用URL传递参数,由于浏览器对地址栏长度有限制,所以对使用get方式所发送信息的数量有限制,同时浏览器会记录(历史记录,缓存)中会保留请求地址的信息,包括地址后面的数据。get 只能发送普通格式(URL 编码格式)的数据。

 

POST:一般用于向服务器发送数据,对所发送的数据的大小理论上是没有限制,浏览器会缓存记录地址,但是不会记录 post 提交的数据。post 可以发送纯文本、URL编码格式、二进制格式的字符串,形式多样。

 

在以下情况中,请使用 POST 请求:

  • 以提交为目的的请求(类似语义化,get 表示请求,post 表示提交);
  • 发送私密类数据(用户名、密码)(因为浏览器缓存记录特性);
  • 向服务器发送大量数据(数据大小限制区别);
  • 上传文件图片时(数据类型区别);

 

 

 

从输入url到得到html的详细过程

1、浏览器根据DNS服务器得到域名的IP地址

        2、向这个IP的机器发送HTTP请求

        3、服务器收到、处理并返回HTTP请求

        4、浏览器得到返回内容

JS中数组基本操作

  • 不会改变原数组的方法:
    • concat:拼接两个数组,返回拼接后的数组;
    • filter():接收一个函数作为参数,数组中每个元素执行函数,返回执行该函数时返回true的元素组成的数组。
    • map: 返回执行函数后组成的数组;
    • reduce:累加器;
    • slice() 方法返回一个从开始到结束(不包括结束)选择的数组的一部分浅拷贝到一个新数组对象
    • forEach() 方法对数组的每个元素执行一次提供的函数
    • join() 方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。
  • 会改变原数组
    • pop()删除尾部元素,返回删除的元素;
    • push()添加尾部元素,返回数组长度;
    • shift()删除头部元素,返回删除的元素;
    • unshift()网头部添加元素,返回长度;
    • splice()添加、删除,

 

 

 

 

 

 

你怎么理解同源策略?

  • 同源限制主要是为了安全,如果没有同源限制存在浏览器中的cookie等其他数据可以任意读取,不同域下DOM任意操作,Ajax任意请求,这会有很严重的安全隐患;
  • 为了保护不同站点和用户的隐私安全,个浏览器便制定了同源策略;
  • 所谓同源即要求协议、域名、端口号完全相同;
  • 一般解决跨域的方式常用的有JSONP(只支持 GET 请求)、跨域资源共享CORS(服务器端通过设置Access-Control-Allow-Origin来进行的)、服务器端设置代理请求:服务器端不受同源策略限制

 

阅读以下代码

如果运行上面代码,3秒延迟后你会看到,实际上每次打印输出是4,而不是期望的0123 

 

阅读以下代码

输出2

 

输出 undefine 6

分析如下:
开始执行代码时,会创建一个全局对象window
js执行代码过程可以分: 词法分析期和执行期
第一步词法分析包括:形参分析、实参分析、变量声明分析、函数声明分析。分析出的结果作为对象的属性和方法
window对象在词法分析期 得到的属性和方法有:
window.a=function(xx){this.x=xx;return this} 
window.x=undefined
window.y=undefined

代码执行期:
/*先执行 window.a(5) =》window.a=function(xx){this.x=xx;return this} 函数中的this指代对象是window.
得出window.x=5,   此时,全局域中window.x=undefined 变成 window.x=5  
然后   return  window 赋值给 x 即:x=window ,
最终这x=window这句赋值语句 把 window.x=5改成 window.x=window  */
 x=a(5);    
 /*先执行 window.a(6) =》window.a=function(xx){this.x=xx;return this} 函数中的this指代对象是window.
得出window.x=6,   把全局域中window.x=window变成 window.x=6    
然后   return  window 赋值给 y  即:y=window  
y=window  赋值语句把window.y=undefined 变成了 window.y=window  */
 y=a(6);
//
综上所述:window.x=6     window.y=window
console.log(x.x);     //输出x.x 相当于:(window.x).x=6.x------->window对象中没有 6.x属性      则输出undefined
console.log(y.x);      //输出 y.x 相当于:(window.y).x=window.x------------>window对象中有window.x这个属性  则输出6 

 

 

 

阅读以下代码:

 

结果:1 11 show11

 

 

作为对象的方法来调用,this指向方法的调用者,即母体对象,不管被调用的函数,声明的时候属于方法,还是函数

 

 

 

 

 

 

 

 

 

阅读以下代码:

 

第一行:

可以得知,第一个fun(0)是在调用第一层fun函数。第二个fun(1)是在调用前一个fun的返回值的fun函数,所以:

第后面几个fun(1),fun(2),fun(3),函数都是在调用第二层fun函数

遂:

在第一次调用fun(0)时,oundefined

第二次调用fun(1)m1,此时fun闭包了外层函数的n,也就是第一次调用的n=0,即m=1n=0,并在内部调用第一层fun函数fun(1,0);所以o0

第三次调用fun(2)m2,但依然是调用a.fun,所以还是闭包了第一次调用时的n,所以内部调用第一层的fun(2,0);所以o0

第四次同理;

即:最终答案为undefined,0,0,0

 

第二行

先从fun(0)开始看,肯定是调用的第一层fun函数;而他的返回值是一个对象,所以第二个fun(1)调用的是第二层fun函数,后面几个也是调用的第二层fun函数。

遂:

在第一次调用第一层fun(0)时,oundefined

第二次调用 .fun(1)m1,此时fun闭包了外层函数的n,也就是第一次调用的n=0,即m=1n=0,并在内部调用第一层fun函数fun(1,0);所以o0

第三次调用 .fun(2)m2,此时当前的fun函数不是第一次执行的返回对象,而是第二次执行的返回对象。而在第二次执行第一层fun函数时时(1,0)所以n=1,o=0,返回时闭包了第二次的n,遂在第三次调用第三层fun函数时m=2,n=1,即调用第一层fun函数fun(2,1),所以o1

第四次调用 .fun(3)m3,闭包了第三次调用的n,同理,最终调用第一层fun函数为fun(3,2);所以o2

即最终答案:undefined,0,1,2

 

第三行:

根据前面两个例子,可以得知:

fun(0)为执行第一层fun函数,.fun(1)执行的是fun(0)返回的第二层fun函数,这里语句结束,遂c存放的是fun(1)的返回值,而不是fun(0)的返回值,所以c中闭包的也是fun(1)第二次执行的n的值。c.fun(2)执行的是fun(1)返回的第二层fun函数,c.fun(3)执行的fun(1)返回的第二层fun函数。

遂:

在第一次调用第一层fun(0)时,oundefined

第二次调用 .fun(1)m1,此时fun闭包了外层函数的n,也就是第一次调用的n=0,即m=1n=0,并在内部调用第一层fun函数fun(1,0);所以o0

第三次调用 .fun(2)m2,此时fun闭包的是第二次调用的n=1,即m=2n=1,并在内部调用第一层fun函数fun(2,1);所以o1

第四次.fun(3)时同理,但依然是调用的第二次的返回值,遂最终调用第一层fun函数fun(3,1),所以o还为1

即最终答案:undefined,0,1,1

 

 

猜你喜欢

转载自blog.csdn.net/this_name_true/article/details/85676724
今日推荐