JavaScript常见基础面试题

1 JavaScript的基本数据类型

基本数据类型:Number、String 、Boolean 、Null、Undefined
引用类型:Function、Array、Object、Date、RegExp(正则表达式)
Object 是 JavaScript 中所有对象的父对象
数据封装类对象:Object、Array、Boolean、Number 和 String
其他对象:Arguments、Math、Error
新类型:Symbol

栈(stack):自动分配内存空间,大小固定,会自动释放内存,存储基本数据类型的值以及引用类型的地址(或称为“引用”),随着函数或者代码块执行完毕而结束。

堆(heap):动态分配的内存,自动调整大小,不会自动释放内存,存储引用类型的值,该值会产生地址(或称为“引用”)存储在栈内存中,需要手动释放,否则会造成内存泄漏。

2 数组方法

1、​push
在数组的末尾添加一项或者多项, 返回添加数据后的数组的新长度:array.push(…data);
2、pop
在数组的末尾删除一项, 返回被删除的项:array.pop();
3、unshift
在数组的首位添加一项或者多项, 返回添加数据后的数组的新长度:array.unshift(…data);
4、shift
在数组的首位删除一项, 返回被删除的项: array.shift();
5、splice
splice: 增删改, 返回被删除的项组成的新数组

语法: array.splice(起始下标, 删除的个数, […data]);
增加:array.splice(起始下标, 删除个数, …data);
删除:array.splice(起始下标, 删除个数);
替换: array.splice(起始下标, 删除个数, …data);

6、concat
拼接数组和项, 返回新数组:array.concat(…data);
7、slice
截取 用法与字符串一模一样, 返回截取出来的新数组:array.slice([起始下标], [结束下标]);
8、reverse
数组翻转, 改变原数组, 具有返回值, 返回翻转以后的数组:array.reverse();
9、join
将数组按照拼接符连接起来, 返回字符串:array.join(连接符),连接符可以是一切字符, 默认以 ‘ , ’ 作为连接符
10、indexOf
从前往后 查找对应的项在数组中出现的位置,如果有返回下标,如果没有返回-1
11、lastIndexOf
从后往前 查找对应的项在数组中出现的位置,如果有返回下标,如果没有返回-1
12、sort
数组.sort([函数]); 默认按照字符串的排序规则进行排序
13、every
对数组的每一个项做一些判断, 根据函数的返回值, 如果每个项执行函数的返回值都是true, 返回true. 如果有一个是false 返回false
14、some
some: 对数组的每一个项做一些判断, 根据函数的返回值, 如果每个项执行函数的返回值都是false, 返回false. 如果有一个是true 返回true
15、filter
filter: 对数组中的做一些过滤, 会将符合条件的(函数的返回值是true)项组成一个新数组返回;
16、map
map\forEach: for循环
map: for循环 将每个函数的返回值组成新数组返回 造成内存浪费
forEach: 纯粹的for循环 没有返回值
17、forEach
map\forEach: for循环
map: for循环 将每个函数的返回值组成新数组返回 造成内存浪费
forEach: 纯粹的for循环 没有返回值

3 字符串方法

1、charAt
获取指定下标对应的字符
2、charCodeAt
获取指定下标对应的字符的ASCII码
3、indexOf
indexOf: 查找指定的字符在字符串中出现的位置 如果有返回下标 如果没有返回-1
4、lastIndexOf
lastIndexOf: 查找指定的字符在字符串中最后出现的位置 如果有返回下标 如果没有返回-1
5、substring
语法: 字符串.substring([起始下标], [结束下标]);
6、slice
语法: 字符串.slice([起始下标], [结束下标]);
7、replace
string.replace(要被替换的字符/正则, 被替换的新字符/函数);
8、split
作用: 将字符串按照指定的分割符进行分割 返回数组:string.split(‘分割符’);
9、toUpperCase
转大写: 字符串.toUpperCase()
10、toLowerCase
转小写 字符串.toLowerCase()
11、trim
去除字符串左右空格 字符串.trim()

4 Ajax和JSONPS 使用

全称 : Asynchronous Javascript And XML
异步请求:就是向服务器发送请求的时候,我们不必等待结果,而是可以同时做其他的事情,等到有了结果它自己会根据设定进行后续操作,与此同时,页面是不会整页刷新,提高了用户体验。

优势:
1.无刷新在页面与服务器通信,更新页面,用户体验好,异步与服务器通信。
2.不需要打断用户的操作,具有更加迅速的响应能力。
3.前端和后端负载平衡。可以把以前一些服务器负担的工作转嫁到客户端,利用客户端闲置的能力来处理,减轻服务器和带宽的负担,节约空间和宽带租用成本。并且减轻服务器的负担,ajax的原则是“按需取数据”,可以最大程度的减少冗余请求,和响应对服务器造成的负担。
4.界面与应用分离,Ajax使WEB中的界面与应用分离(也可以说是数据与呈现分离),有利于分工合作、减少非技术人员对页面的修改造成的WEB应用程序错误、提高效率、也更加适用于现在的发布系统。
5.基于标准化的并被广泛支持的技术,不需要下载插件或者小程序。

缺点:
1.AJAX干掉了Back和History功能,即对浏览器机制的破坏。
2.AJAX的安全问题,Ajax技术就如同对企业数据建立了一个直接通道,这使得开发者在不经意间会暴露比以前更多的数据和服务器逻辑。Ajax也难以避免一些已知的安全弱点,诸如跨站点脚步攻击、SQL注入攻击和基于Credentials的安全漏洞等等
3.对搜索引擎支持较弱。
4.客户端过肥,太多客户端代码造成开发上的成本。
5.违背URL和资源定位的初衷,采用了Ajax技术,也许你在该URL地址下面看到的和我在这个URL地址下看到的内容是不同的。

创建Ajax的过程:

  1. 创建XMLHttpRequest对象(异步调用对象)
    var xhr = new XMLHttpRequest();
  2. 创建新的Http请求(方法、URL、是否异步)
    xhr.open(‘get’,’example.php’,false);
  3. 设置响应HTTP请求状态变化的函数。
    onreadystatechange事件中readyState属性等于4。响应的HTTP状态为200(OK)或者304(Not Modified)。
  4. 发送http请求
    xhr.send(data);
  5. 获取异步调用返回的数据
    注意:
  6. 页面初次加载时,尽量在web服务器一次性输出所有相关的数据,只在页面加载完成之后,用户进行操作时采用ajax进行交互。
  7. 同步ajax在IE上会产生页面假死的问题。所以建议采用异步ajax。
  8. 尽量减少ajax请求次数

JSONPS 是利用script 标签没有同源策略的限制(算是一个漏洞),来达到与第三方通信,从而实现跨域。
我们通常使用js代码动态创建一个script标签,src引用第三方api的地址,并提供一个回调函数的function name
<!doctype html>

<html>
    <head>
        <meta charset="utf-8">
        <title>无标题栏文档</title>
    </head>
    <body>
        <script type="text/javascript">
            function jsonp(res) {
                console.log(res)   // 后台返回的数据
            }
        </script>
        // 这是后台配合 整理出来的文件地址  我们加上callback 回调函数
        <script src="https://xxx.com/aaa/aa/a.js?callback='jsonp'" type="text/javascript"></script>
    </body>
</html>

JSONP并不使用XMLHttpRequest对象加载资源,而是通过script标签把资源当做普通的javascript脚本来加载,所以不存在跨域问题,也不是真正的AJAX。

5 Javascript作用链域

作用域链的原理和原型链很类似,如果这个变量在自己的作用域中没有,那么它会寻找父级的,直到最顶层。
注意:JS没有块级作用域,若要形成块级作用域,可通过(function(){})();立即执行的形式实现。

6 谈谈this的理解

  1. this总是指向函数的直接调用者(而非间接调用者)
  2. 如果有new关键字,this指向new出来的那个对象
  3. 在事件中,this指向目标元素,特殊的是IE的attachEvent中的this总是指向全局对象window。

7 eval是做什么的?

它的功能是把对应的字符串解析成JS代码并运行;应该避免使用eval,不安全,非常耗性能(2次,一次解析成js语句,一次执行)。

8 什么是window对象? 什么是document对象?

window对象代表浏览器中打开的一个窗口。document对象代表整个html文档。实际上,document对象是window对象的一个属性。

9 null,undefined的区别?

null表示一个对象被定义了,但存放了空指针,转换为数值时为0。
undefined表示声明的变量未初始化,转换为数值时为NAN。
typeof(null) – object;
typeof(undefined) – undefined

10 ES6新特性

  1. let\ const
    let表示声明变量,而const表示声明常量,两者都为块级作用域;const 声明的变量都会被认为是常量,意思就是它的值被设置完成后就不能再修改了 如果const的是一个对象,对象所包含的值是可以被修改的。抽象一点儿说,就是对象所指向的地址没有变就行:

  2. 箭头函数
    ES6 中,箭头函数就是函数的一种简写形式,使用括号包裹参数,跟随一个 =>,紧接着是函数体;

在使用箭头函数时要注意以下几点:

如果只有一个参数,()可以省

不需要 function 关键字来创建函数
省略 return 关键字
继承当前上下文的 this 关键字
函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象
不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误
不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替
不可以使用yield命令,因此箭头函数不能用作 Generator 函数
3.模板字符串
需要拼接字符串的时候尽量改成使用模板字符串,模板字符串可以使字符串的拼接更加的简洁和直观
4.结构赋值
从数组和对象中提取值,对变量进行赋值,这被称为解构,解构赋值可以直接使用对象的某个属性,而不需要通过属性访问的形式使用:let[a,b,c]=[1,2,3]
5.拓展运算符:arr=[…arr1,…arr2];
6.数组新增:map、forEach、filter、reduce(算平均数)
7.set的几种常见方法

let set = new Set([1,1,2,3])
console.log(set); // 输出:1,2,3  原因:set方法自动去重
console.log(set.add('z'));  // 输出:1,2,3,z
console.log(set.has('z')); //输出:true  原因:存在返回true,否则false
console.log(set.delete(1)); //输出:true  原因:删除成功返回true,失败返回false
set.clear();
console.log(set.size); //输出:0  原因:set.clear() 已经将对象清空
  1. Promise
    1、Promise对象是一个构造函数
    2、Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject:
    resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”
    reject函数的作用是,将Promise对象的状态从“未完成”变为“失败
    3、实例方法:Promise构建出来的实例存在以下方法
    then():then是实例状态发生改变时的回调函数,第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数
    catch():catch()方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数
    finally():finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作
    4、构造函数方法:Promise构造函数存在以下方法
    all():Promise.all()方法用于将多个 Promise实例,包装成一个新的 Promise实例
    race():Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实
    allSettled():Promise.allSettled()方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例
    resolve():将现有对象转为 Promise对象
    reject():Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected

11 节流和防抖

防抖:防止抖动,连续调用只有最后一次生效
节流:节省流量,固定时间只触发一次

12 闭包(closure)

闭包指的是一个函数可以访问另一个函数作用域中变量。常见的构造方法,是在一个函数内部定义另外一个函数。内部函数可以引用外层的变量;外层变量不会被垃圾回收机制回收。
注意,闭包的原理是作用域链,所以闭包访问的上级作用域中的变量是个对象,其值为其运算结束后的最后一个值。
优点:避免全局变量污染。缺点:容易造成内存泄漏。
例子:

function makeFunc() {
    var name = "Mozilla";
    function displayName() {
        console.log(name); 
    }
    return displayName;
}
var myFunc = makeFunc();
myFunc();   //输出Mozilla

myFunc 变成一个 闭包。闭包是一种特殊的对象。它由两部分构成:函数,以及创建该函数的环境。环境由闭包创建时在作用域中的任何局部变量组成。在我们的例子中,myFunc 是一个闭包,由 displayName 函数和闭包创建时存在的 “Mozilla” 字符串形成。

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

除了正常模式运行外,ECMAscript添加了第二种运行模式:“严格模式”。
作用:

  1. 消除js不合理,不严谨地方,减少怪异行为
  2. 消除代码运行的不安全之处,
  3. 提高编译器的效率,增加运行速度
  4. 为未来的js新版本做铺垫。

14 如何判断一个对象是否属于某个类?

使用instanceof 即if(a instanceof Person){alert(‘yes’);}

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

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

16 Javascript中,执行时对象查找时,永远不会去查找原型的函数?

Object.hasOwnProperty(proName):是用来判断一个对象是否有你给出名称的属性。不过需要注意的是,此方法无法检查该对象的原型链中是否具有该属性,该属性必须是对象本身的一个成员。

17 对JSON的了解?

全称:JavaScript Object Notation
JSON中对象通过“{}”来标识,一个“{}”代表一个对象,如{“AreaId”:”123”},对象的值是键值对的形式(key:value)。JSON是JS的一个严格的子集,一种轻量级的数据交换格式,类似于xml。数据格式简单,易于读写,占用带宽小。
两个函数:
JSON.parse(str)
解析JSON字符串 把JSON字符串变成JavaScript值或对象
JSON.stringify(obj)
将一个JavaScript值(对象或者数组)转换为一个 JSON字符串
eval(‘(‘+json+’)’)
用eval方法注意加括号 而且这种方式更容易被攻击

18 JS延迟加载的方式有哪些?

JS的延迟加载有助与提高页面的加载速度。
defer和async、动态创建DOM方式(用得最多)、按需异步载入JS
defer:延迟脚本。立即下载,但延迟执行(延迟到整个页面都解析完毕后再运行),按照脚本出现的先后顺序执行。
async:异步脚本。下载完立即执行,但不保证按照脚本出现的先后顺序执行。

19 同步和异步的区别?

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

20 什么是跨域问题

跨域问题‌是指不同站点之间使用‌AJAX无法相互调用的问题。这是由于‌浏览器的‌同源策略造成的,同源策略限制了来自不同源的网页无法进行交互,以保护用户的安全。当协议、域名或端口号中任意一个不同,就视为不同的源,从而引发跨域问题。

为什么会有跨域问题
跨域问题的根本原因是浏览器的同源策略。同源策略是浏览器的一种安全机制,它限制了来自不同源的网页之间的交互,以防止恶意网站窃取数据。当协议、域名或端口号中任意一个不同,浏览器就会阻止这些网页之间的交互,从而引发跨域问题。

如何解决跨域问题
解决跨域问题的方法有多种,以下是一些常见的方法:

‌1.使用‌CORS(跨源资源共享)‌: 在服务器端设置CORS头部信息,允许特定域名的访问。例如,可2.以在web.xml中配置过滤器,允许跨域访问。
‌3.使用注解‌: 在‌Spring框架中,可以使用@CrossOrigin注解来允许特定域名的访问。
‌4.配置‌filter‌: 实现自定义的filter,重写doFilter方法,设置允许跨域访问。
‌5.配置‌Spring Boot内置Tomcat‌: 在application.yml中添加相关配置,允许跨域访问。
‌6.外置Tomcat解决方案‌: 将Spring Boot项目打包成WAR包部署在Tomcat中,通过配置Tomcat的filter来解决跨域问题。

22 页面编码和被请求的资源编码如果不一致如何处理?

若请求的资源编码,如外引js文件编码与页面编码不同。可根据外引资源编码方式定义为 charset=“utf-8"或"gbk”。
比如:http://www.yyy.com/a.html 中嵌入了一个http://www.xxx.com/test.js
a.html 的编码是gbk或gb2312的。 而引入的js编码为utf-8的 ,那就需要在引入的时候

<script src="http://www.xxx.com/test.js&quot; charset="utf-8"></script>

23 模块化开发怎么做?

模块化开发指的是在解决某一个复杂问题或者一系列问题时,依照一种分类的思维把问题进行系统性的分解。模块化是一种将复杂系统分解为代码结构更合理,可维护性更高的可管理的模块方式。对于软件行业:系统被分解为一组高内聚,低耦合的模块。
(1)定义封装的模块
(2)定义新模块对其他模块的依赖
(3)可对其他模块的引入支持。在JavaScript中出现了一些非传统模块开发方式的规范。 CommonJS的模块规范,AMD(Asynchronous Module Definition),CMD(Common Module Definition)等。AMD是异步模块定义,所有的模块将被异步加载,模块加载不影响后边语句运行。

24 AMD(Modules/Asynchronous-Definition)、CMD(Common Module Definition)规范区别?

AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。
区别:

  1. 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。
  2. CMD 推崇依赖就近,AMD 推崇依赖前置。
  3. AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单一。

CommonJS 规范是为了解决 JavaScript 的作用域问题而定义的模块形式,可以使每个模块它自身的命名空间中执行。该规范的主要内容是,模块必须通过 module.exports 导出对外的变量或接口,通过 require() 来导入其他模块的输出到当前模块作用域中,module标识模块本身。
(function (module, exports){})(module, module.exports)
require是全局定义的,立即执行函数提供 module 和 exports 两个外部变量,模块就放在这个立即执行函数里面。模块的输出值放在 module.exports 之中,这样就实现了模块的加载。
nodejs就是参照CommonJS的规范实现了自己的模块化系统,不过它的自执行函数提供外部变量被内置了,所以我们是看不到的。
当我们需要用到某个依赖的模块的时候,直接require进来,就可以用了,也就是“依赖就近”,用到再引入模块。
另外由于commonJS更多的是运行在服务器端,代码都在本地,直接从硬盘读取,所以它是同步加载模块代码的,速度不会受影响。

服务端的模块概念形成,浏览器客户端的模块,在“不能采用同步加载”,“需要异步加载”的背景下,ADM规范诞生了。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。AMD也采用require()语句加载模块,但是不同于CommonJS,它要求两个参数:
require([module], callback);
第一个参数[module],是一个数组,里面的成员就是要加载的模块;第二个参数callback,则是加载成功之后的回调函数。
当我们写的当前模块要依赖某些模块的时候,就需要文件开头这么写,先引入依赖的模块,也就是“依赖前置”。

// CMD
define(function(require, exports, module) {
    var a = require('./a')
    a.doSomething()
    // 此处略去 100 行
    var b = require('./b') // 依赖可以就近书写
    b.doSomething()
})
// AMD 默认推荐
define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好
    a.doSomething();
    // 此处略去 100 行
    b.doSomething();
})

import和require的区别
加载时机不同:import是在编译时加载,必须放在文件的开头,require是在运行时加载,可以放在代码的任何位置。
所属规范不同:import是ES6(ECMAScript 2015)引入的关键字,属于ES模块化语法规范,require是CommonJS规范的一部分,主要用于Node.js环境。
动态绑定不同:import提供静态分析,支持宏和类型检验,require提供动态绑定,更适合服务器或浏览器环境。
导入值的修改:require导入的值被修改时,源对象不会被改变,相当于深拷贝,import导入的对象值被改变时,源对象也会被改变,相当于浅拷贝。

25 requireJS的核心原理是什么?(如何动态加载的?如何避免多次加载的?如何缓存的?)

核心是js的加载模块,通过正则匹配模块以及模块的依赖关系,保证文件加载的先后顺序,根据文件的路径对加载过的文件做了缓存。

26 call和apply

call()方法和apply()方法的作用相同,动态改变某个类的某个方法的运行环境。他们的区别在于接收参数的方式不同。在使用call()方法时,传递给函数的参数必须逐个列举出来。使用apply()时,传递给函数的是参数数组。

27 谈一谈你对ECMAScript6的了解

28 documen.write和 innerHTML的区别

document.write()只能重绘整个页面
innerHTML可以重绘页面的一部分

setTimeout(function(){
       document.write('<p>5 secs later</p>');
}, 5000);

window.onload = function() { document.write("HI")};

29 回流与重绘

当渲染树中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(reflow)。每个页面至少需要一次回流,就是在页面第一次加载的时候。在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树。完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程成为重绘

30 DOM操作

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

31

32 那些操作会造成内存泄漏

全局变量、闭包、DOM清空或删除时,事件未清除、子元素存在引用

33 什么是Cookie 隔离?(或者:请求资源的时候不要带cookie怎么做)

通过使用多个非主要域名来请求静态文件,如果静态文件都放在主域名下,那静态文件请求的时候带有的cookie的数据提交给server是非常浪费的,还不如隔离开。因为cookie有域的限制,因此不能跨域提交请求,故使用非主要域名的时候,请求头中就不会带有cookie数据,这样可以降低请求头的大小,降低请求时间,从而达到降低整体请求延时的目的。同时这种方式不会将cookie传入server,也减少了server对cookie的处理分析环节,提高了server的http请求的解析速度。

34 如何删除一个cookie?

1) 将cookie的失效时间设置为过去的时间(expires)

document.cookie = ‘user=’+ encodeURIComponent(‘name’) + ';
expires=’+ new Date(0);
2) 将系统时间设置为当前时间往前一点时间

var data = new Date();
date.setDate(date.getDate()-1);

35 响应事件

onclick鼠标点击某个对象;onfocus获取焦点;onblur失去焦点;onmousedown鼠标被按下

36 flash和js通过什么类如何交互?

Flash提供了ExternalInterface接口与JavaScript通信,ExternalInterface有两个方法,call和addCallback,call的作用是让Flash调用js里的方法,addCallback是用来注册flash函数让js调用。

37 Flash与Ajax各自的优缺点?

Flash:适合处理多媒体、矢量图形、访问机器。但对css、处理文本不足,不容易被搜索。
Ajax:对css、文本支持很好,但对多媒体、矢量图形、访问机器不足。

38 有效的javascript变量定义规则

第一个字符必须是一个字母、下划线(_)或一个美元符号($);其他字符可以是字母、下划线、美元符号或数字。

39 XML与JSON的区别?

  1. 数据体积方面。JSON相对于XML来讲,数据的体积小,传递的速度更快些。
  2. 数据交互方面。JSON与JavaScript的交互更加方便,更容易解析处理,更好的数据交互。
  3. 数据描述方面。JSON对数据的描述性比XML较差。
  4. 传输速度方面。JSON的速度要远远快于XML。

40 HTML与XML的区别?

(1)XML用来传输和存储数据,HTML用来显示数据;
(2)XML使用的标签不用预先定义
(3)XML标签必须成对出现
(4)XML对大小写敏感
(5)XML中空格不会被删减
(6)XML中所有特殊符号必须用编码表示
(7)XML中的图片必须有文字说明

41 渐进增强与优雅降级

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

42 Web Worker和Web Socket?

web socket:在一个单独的持久连接上提供全双工、双向的通信。使用自定义的协议(ws://、wss://),同源策略对web socket不适用。
web worker:运行在后台的JavaScript,不影响页面的性能。
创建worker:var worker = new Worker(url);
向worker发送数据:worker.postMessage(data);
接收worker返回的数据:worker.onmessage
终止一个worker的执行:worker.terminate();

43 JS垃圾回收机制?

  1. 标记清除:
    这个算法把“对象是否不再需要”简化定义为“对象是否可以获得”。
    这个算法假定设置一个叫做根(root)的对象(在Javascript里,根是全局对象)。定期的,垃圾回收器将从根开始,找所有从根开始引用的对象,然后找这些对象引用的对象。从根开始,垃圾回收器将找到所有可以获得的对象和所有不能获得的对象。

  2. 引用计数:
    这是最简单的垃圾收集算法。此算法把“对象是否不再需要”简化定义为“对象有没有其他对象引用到它”。如果没有引用指向该对象(零引用),对象将被垃圾回收机制回收。
    该算法有个限制:无法处理循环引用。两个对象被创建,并互相引用,形成了一个循环。它们被调用之后不会离开函数作用域,所以它们已经没有用了,可以被回收了。然而,引用计数算法考虑到它们互相都有至少一次引用,所以它们不会被回收。

44 web应用从服务器主动推送data到客户端的方式?

JavaScript数据推送:commet(基于http长连接的服务器推送技术)。
基于web socket的推送:SSE(server-send Event)

45 attribute与property的区别?

attribute是dom元素在文档中作为html标签拥有的属性
property是dom元素在js中作为对象拥有的属性。
所以,对于html的标准属性来说,attribute和property是同步的,是会自动更新的。但对于自定义属性,他们不同步。

46 Ajax请求的页面历史记录状态问题?

(1)通过location.hash记录状态,让浏览器记录Ajax请求时页面状态的变化。
(2)通过HTML5的history.pushstate,来实现浏览器地址栏的无刷新改变。

47 事件代理 (event delegation)

当我们需要对很多元素添加事件的时候,可以通过将事件添加到它们的父节点而将事件委托给父节点来触发处理函数。也可以称为事件委托。
这主要得益于DOM2中的事件冒泡机制(最好要答出)
益处:需要创建的以及驻留在内存中的事件处理器少了,节省内存,提升性能。

48 JavaScript 中 this 是如何工作

函数被调用,被谁调用那函数中的this就是谁,没有调用者就是window。所以自执行函数的this也是window

function fn() {
console.log(this)
}
fn() // this -> window

const obj = {
name: ‘https://www.jkys120.com/article/95497/’,
getName: function () {
console.log(this);
return this.name
}
}
obj.getName() // this-> obj
箭头函数中的this是外部作用域的this,解决了之前要缓存this的弊端。

const outer = function outer () {
console.log(this);
return function inner () {
console.log(this)
}
}
const obj = {
outer
}
obj.outer()()
const outer = function outer () {
console.log(this);
return () => console.log(this)

}
const obj = {
outer
}
obj.outer()()
给元素绑定事件方法,方法中的this是当前绑定的元素。

构造函数中,this绑定到当前创建的对象实例。

使用apply或call调用 this 将会被显式设置为函数调用的第一个参数。bind也可,属于预处理this

49 原型继承 (prototypal inheritance) 的原理

主要用到了原型链查找。
每个函数F都有一个原型对象 F.prototype
,原型会定义F类的公用方法或者属性。
当我们new F 创建一个实例o的时候,会给o添加一个__proto__属性,通过__protp__会找到 F.prototype,也就是所属类的原型。
当我们通过o访问一个属性的时候,比如o.name,会先在实例o上查找,没有的话js会通过__proto__去类的原型上找,由于原型也是一个对象,它也有__proto__属性,默认会找到Object的原型。所以,当我们的Child类想通过继承访问Super类上的属性/方法,可以通过设置Child的原型,能访问到Super的原型,就可以访问Super类的公用属性和方法了。
例如,

Child.prototype = new Super;
把Child的原型指向Super的一个实例s,Child的实例o通过访问原型,能找到s,s通过__proto__可以找到它所属类的原型,也就是Super.prototype ,也就能访问Super类上的共有属性/方法。
当然这只是一种方式,还有其他方式,这里不再赘述。

50

51 JavaScript 宿主对象 (host objects) 和原生对象 (native objects) 的区别?

宿主对象是指DOM和BOM等由宿主框架通过某种机制注册到JavaScript引擎中的对象。原生对象是Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、Math等ECMAScript官方定义的对象。

52 解释 Function.prototype.bind

Function原型上定义的方法,所有函数都可以访问使用。主要应用场景在绑定函数执行的this,并返回一个新函数,可以在我们要调用的时候才执行。原理是函数的预处理思想,把this当做参数预置。

53 在什么时候你会使用 document.write()

加载需要配合JS脚本使用的外部CSS文件

document.write(‘’);

将所有需要用到JS的样式都放到这个外部样式表中,如果浏览器不禁用JS,那么该样式表就会被顺利加载,否则页面就不会使用该样式。

在新的窗口中写入新的页面数据时
由于document.write会重写整个页面,异步调用会影响本页面的文档,如果在新窗口空白页调用,就没影响了。新开一个窗口,把本页面取到的数据在新窗口展示。。
document.open();
document.write(‘anthing’)
document.close();
由于带来的弊端较多,一般不建议使用。要对DOM进行操作时,还是应当使用安全且对DOM的友好的API方法,以避免不必要的问题出现。

54 事件冒泡机制 (event bubbling)

W3C在DOM2中添加了一个事件模型,DOM事件流存在三个阶段,事件捕获,目标阶段,冒泡阶段。也就是当事件触发的时候,浏览器会从根节点开始,又外到内的进行事件传播,直到目标元素,如果在此捕获阶段绑定事件,https://www.jkys120.com/article/95497/都会触发。然后从目标元素,事件又会沿着当前元素的包含关系,由内而外的传递,每一级都可以感知到事件触发。通过DOM2中的addEventListener(event, listner, useCapture),第三个参数默认为false,也就是不绑定捕获阶段。如果想禁止事件在冒泡阶段传播,只需要在要禁止的目标元素的事件方法里,加上e.stopPropagation方法

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值