面闭 — JavaScript
Ajax 请求的步骤
第一步(得到 XMLHttpRequest)
第二步(打开与服务器的链接)
第三步(发送请求)
xmlHttp.send(null);如果括号里不给 null 可能会造成部分浏览器无法发送;
第四步
在 xmlHttp 对象的一个事件上注册监听器: onreadstatechange
得到的 5 个状态
>0
状态:刚创建,还没有调用 open() 方法;
>1
状态:请求刚开始,调用了open()方法,但是没有调用 send 方法;
>2
状态:调用完了 send() 方法;
>3
状态:服务器已经开始响应。但不表示响应结束;
>4
状态:服务器响应结束!;
得到 xmlHttp 对象状态
var state = xmlHttp.redayState; // 可能是 0,1,2,3,4
得到服务器的响应状态码
var state = xmlHttp.status; // 可能是 200、404、500
得到服务器的响应内容
Ajax 的缺点
(1)、ajax 不支持浏览器 back 按钮
(2)、安全问题 ajax 暴露了与服务器交互的细节。
(3)、对搜索引擎的支持比较弱
(4)、破坏了程序的异常机制
什么是 Ajax 和 JSON,它们的优缺点
Ajax 全称 asynchronous JavaScript and XML,即异步 JavaScript 和 xml,用于在 web 页面中事先异步数据交互,实现页面局部刷新。
优点:可以使得页面不重载全部内容的情况下加载局部内容,降低数据传输量,避免用户不断刷新或者跳转页面,提高用户体验。
缺点:对搜索引擎不友好,要实现 ajax 下的前后退功能成本较大,可能造成请求数量增加跨域问题限制;
json 是一种轻量级的数据交换格式,ECMA 的一个子级
优点:轻量级、易于人的阅读和编写,便于机器(JavaScript)解析,支持复合数据类型(数组、对象、字符串、数字)
Ajax 请求的时候 get 和 post 方式的区别
get 一般用来进行查询操作,url 地址有长度限制,请求的参数都暴露在 url 地址中,如果传递中文参数,需要自己进行编码操作,安全性低
post 请求方式主要提交数据,没有数据长度的限制,提交的数据内容存在于 http 请求体中,数据不会暴露在 url 地址中。
jsonp的原理,以及为什么不是真正的 ajax
jsonp 并不是一种数据格式,而 json 是一种数据格式,jsonp 是用来解决跨域获取数据的一种解决方案,具体是通过动态创建 script 标签,然后通过标签的 src 属性获取 js 文件中的 js 脚本,该脚本的内容是一个函数调用,参数就是服务器返回的数据,为了处理这些返回的数据,需要事先在页面定义好回调函数,本质上不是使用 ajax 技术。
阐述一下异步加载
(1) 异步加载的方案:动态插入 script 标签
(2) 通过 ajax 去获取 js 代码,然后通过 eval 执行
(3) script 标签上添加 defer 或 async 属性
(4) 创建并插入 iframe,让它异步执行 js
post 和 get 的区别,何时使用 post
get:一般用于信息获取,使用 url 传递参数,对所有发送信息的数量也有限制,一般在 2000 个字符,有的浏览器 8000 个字符
post:一般用于修改服务器上的资源,对于发送的信息没有限制
在以下情况中,请使用 post 请求:
(1) 无法使用缓存文件(更新服务器上的文件或数据库)
(2) 向服务器发送大量数据(post 没有数据限制)
(3) 发送包含未知字符的用户输入时,post 比 get 更稳定也更可靠
数组去重的方法
排序方法
1 | function distinct(arr){ |
对象方法
1 | function unique(arr){ |
js 的作用域
作用域说明:一般理解指一个变量的作用范围
1、全局作用域
(1)全局作用域在页面打开时被创建,页面关闭时被销毁
(2)编写在 script 标签中的变量和函数,作用域为全局,在页面的任意位置都可以访问到
(3)在全局作用域中有全局对象 window,代表一个浏览器窗口,由浏览器创建,可以直接调用
(4)全局作用域中声明的变量和函数会作为 window 对象的属性和方法保存
2、函数作用域
(1)调用函数时,函数作用域被创建,函数执行完毕,函数作用域被销毁
(2)每调用一次函数就会被创建一个新的函数作用域,他们之间是相互独立的。
(3)在函数作用域中可以访问到全局作用域的变量,在函数外无法访问到函数作用域内的变量
(4)在函数作用域中访问变量、函数时,会先在自身作用域中寻找,若没有找到,则会到函数的上一级作用域中寻找,一直到全局作用域
说说你对闭包的理解
说说你对闭包的理解
使用闭包主要是为了设计私有的方法和变量。
闭包的优点是可以避免全局变量的污染,
缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。
闭包有三个特性:
1、函数嵌套函数
2、函数内部可以引用外部的参数和比变量
3、参数和变量不会被垃圾回收机制回收
请你谈谈 Cookie 的弊端
cookie 虽然在持久保存客户数据提供了方便,分担了服务器存储的负担,但是有很多局限性。
1、每个域名下最多生成 20 个 cookie.
2、浏览器会清理 cookie ,IE、Opera 会清理近期最少使用的 cookie,Firefox 会随机清理 cookie.
3、cookie 最大大约为 4096 字节。
优点:极高的扩展性和可用性。
1、通过良好的编程,控制保存在 cookie 中的 session 对象的大小。
2、通过加密和安全传输技术(SSL),减少 cookie 被破解的可能性。
3、只在 cookie 中存放不敏感数据,即使被盗也不会有重大损失。
4、控制 cookie 的生命期,使之不会永远有效。盗窃者很可能拿到一个过期的 cookie。
缺点:
1、cookie 数量和长度的限制。
2、安全性问题。
3、有些状态不可能保存在客户端。
web storage和 cookie 的区别
cookie 和 session 的区别
1、cookie 数据存放在客户的浏览器上,session 数据放在服务器上。
2、cookie 不是很安全,可以分析存放在本地的 cookie 并进行 cookie 欺骗,考虑到安全应当使用 session。
3、session 会在一定时间内保存在服务器上。当访问增多,会比较占用服务器的性能。
4、单个 cookie 保存的数据不能超过 4k,一个站点最多保存20个 cookie。
使用 typeof bar === “object” 来确定 bar 是否是对象的潜在陷阱是什么?如何避免这个陷阱?
1 | // 避免 null 返回 true |
下面的代码将输出什么到控制台,为什么
1 | (function(){ |
下面输出什么到控制台,为什么
1 | var myObject = { |
封装JavaScript源文件的全部内容到一个函数块有什么意义及理由
这是一个越来越普遍的做法,被许多流行的JavaScript库(jQuery,Node.js等)采用。这种技术创建了一个围绕文件全部内容的闭包,也许是最重要的是,创建了一个私有的命名空间,从而有助于避免不同JavaScript模块和库之间潜在的名称冲突。
这种技术的另一个特点是,允许一个易于引用的(假设更短的)别名用于全局变量。这通常用于,例如,jQuery插件中。jQuery允许你使用jQuery.noConflict(),来禁用 $ 引用到jQuery命名空间。在完成这项工作之后,你的代码仍然可以使用$ 利用这种闭包技术,如下所示:
1 | (function($) { /* jQuery plugin code referencing $ */ } )(jQuery); |
在 JavaScript 源文件的开头包含 use strict 意义和好处
use strict 是一种在JavaScript代码运行时自动实行更严格解析和错误处理的方法。
严格模式的一些主要优点包括:
- 使调试更加容易。
- 防止意外的全局变量。
- 消除 this 强制
- 不允许重复的属性名称或参数值。
- 使eval() 更安全。
- 在 delete使用无效时抛出错误。
考虑以下两个函数。它们会返回相同的东西吗? 为什么相同或为什么不相同
1 | function foo1() |
NaN 是什么?它的类型是什么?你如何可靠地测试一个值是否等于 NaN
NaN 属性代表一个“不是数字”的值。这个特殊的值是因为运算不能执行而导致的,不能执行的原因要么是因为其中的运算对象之一非数字(例如, “abc” / 4),要么是因为运算的结果非数字(例如,除数为零)。
NaN 是 Number;
检测
isNaN
Number.isNaN()
下列代码将输出什么?并解释原因
console.log(0.1 + 0.2);
console.log(0.1 + 0.2 == 0.3);
JavaScript中的数字和浮点精度的处理相同,因此,可能不会总是产生预期的结果。
9.讨论写函数 isInteger(x) 的可能方法,用于确定x是否是整数
在ECMAScript规格说明中,整数只概念上存在:即,数字值总是存储为浮点值。
function isInteger(x) { return (x^0) === x; }
function isInteger(x) { return Math.round(x) === x; }
function isInteger(x) { return (typeof x === ‘number’) && (x % 1 === 0);
function isInteger(x) { return parseInt(x, 10) === x; } // 目变得足够大,为指数形式(例如, 1e+21)
Math.ceil() 和 Math.floor() 在上面的实现中等同于 Math.round()。
下列代码行1-4如何排序,使之能够在执行代码时输出到控制台? 为什么
(function() {
console.log(1);
setTimeout(function(){console.log(2)}, 1000);
setTimeout(function(){console.log(3)}, 0);
console.log(4);
})();
output
1
4
3
2
浏览器有一个事件循环,会检查事件队列和处理未完成的事件。例如,如果时间发生在后台(例如,脚本的 onload 事件)时,浏览器正忙(例如,处理一个 onclick),那么事件会添加到队列中。当onclick处理程序完成后,检查队列,然后处理该事件(例如,执行 onload 脚本)。
同样的, setTimeout() 也会把其引用的函数的执行放到事件队列中,如果浏览器正忙的话。
当setTimeout()的第二个参数为0的时候,它的意思是“尽快”执行指定的函数。具体而言,函数的执行会放置在事件队列的下一个计时器开始。但是请注意,这不是立即执行:函数不会被执行除非下一个计时器开始。这就是为什么在上述的例子中,调用 console.log(4) 发生在调用 console.log(3) 之前(因为调用 console.log(3) 是通过setTimeout被调用的,因此会稍微延迟)。
写一个简单的函数(少于80个字符),要求返回一个布尔值指明字符串是否为回文结构
function isPalindrome(str) {
str = str.replace(/W/g, ‘’).toLowerCase();
return (str == str.split(‘’).reverse().join(‘’));
}
console.log(isPalindrome(“level”)); // logs ‘true’
console.log(isPalindrome(“levels”)); // logs ‘false’
console.log(isPalindrome(“A car, a man, a maraca”)); // logs ‘true’