介绍一下js有哪些内置对象
数据封装类对象:
Object(对象)
Array(数组对象)
Boolean(布尔对象)
Number(数值对象)
String(字符串对象)
其他对象:
Function(函数对象)
Argument(函数参数对象)
Math(数学对象)
Date(日期对象)
RegExp(正则对象)
Error(错误对象)
JavaScript的本地对象,内置对象和宿主对象
本地对象(独立于宿主管径的ECMAScript实现提供的对象):
可以使用new关键字实例化对象的对象,比如我们常用的Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError等这些对象
内置对象 (由ECMAScript实现提供的,独立于宿主环境所有的对象,由ECMAScript程序执行时开始出现,已经被实例化了):
只定义了两个内置对象:Global和Math,这两个通过字面量创建出来的对象
宿主对象
Array和String的常用方法(splice和slice的区别)
Array常用的方法:
四个经常用的:
push():向数组末尾添加元素,个数不限
pop():从数组末尾删除一个元素
shift():从数组头部删除一个元素
unshift():向数组头部添加元素,个数不限
其他的:
splice(增删改操作):splice(操作位置开始的索引值,要删除元素的个数,向删除位置添加的元素值),返回值是被删除元素之后的新数组
arr.splice(2,0,"William")添加一个新元素
arr.splice(2,3,"William")删除从 index 2 ("Thomas") 开始的三个元素,并添加一个新元素 ("William") 来替代被删除的元素
slice从数组中拷贝元素:slice(操作开始的索引值,操作结束的索引值)
concat():连接数组
indexOf():indexOf(要查找的元素,查找开始的位置),如果找到返回第一个找到的索引值,找不到返回-1
sort():对数组进行升序或者是降序,
升序function(a,b){a-b}
降序function(a,b){b-a}
reverse:翻转数组
toString():将数组转换为字符串
join():通过连接符将数组转换为字符串
字符串方法:
slice():slice(操作开始的索引值,结束位置的索引,不包含结束位置)
substr:substr(操作开始位置的索引,拷贝的字符个数)
indexOf():indexOf(要查找的字符内容,查找开始位置的索引值)检索字符串中多个字符组成部分
toUpperCase():转换为大写字符
toLowerCase():转换为小写字符
replace():replace(要替换的内容,替换成什么内容)
split():将字符串转换为数组
trim():去除字符串两端的空格
基本数据类型和引用数据类型有什么区别?
基本数据类型在内存单元中存储的是具体的值,当拷贝过来的值被修改不会改变原来的值
引用数据类型在内存中存储的是一个地址,也就是一个指针,指针指向存储值,这个存储值是在堆中存储
splice和slice有什么区别
slice 方法不会改变原数组,而是返回一个子数组,如果想删除数组中的一段元素还是应该选择splice,
splice方法会改变原数组
强制类型转换和隐式转换
强制类型转换:
parseInt()转换为整型数字
parseFloat()转换为浮点型数字
Number()转换为数字类型
.toString()转换为字符串类型
隐式转换:
==,+-*/,
怎么判断数据类型
1)typeof检测基本数据类型:只能用于检测除了null之外的基本类型的检测,对于复杂类型的检测为object,对于function的检测是Function(检测有风险)
2)instanceof:数据 instanceof 构造函数名,用于判断一个变脸是否属于某个对象的实例
3)constructor:可以获取任意数据的类型名称
4)Object.prototype.toString.call():可以获取任意对象的类型名称
检测null的方式
一般我们不写上面的检测方式,我们直接进行 数据===null
Object.prototype.toString.call(null);
null一定是基本类型
null的类型检测是object 检测结果不准确
对NaN的检测
使用isNaN()这个函数
typeof与 instanceof的异同点
相同点:
相同点
typeof 和instanceof都用来判断一个变量是否为空,或者是什么类型
typeof一般只能返回如下几个结果, number string boolean undefined object function
不同点:
instanceof 用于判断一个变量是否属于某个对象的实例
返回值是布尔值类型
typeof返回的数据类型有哪些?
Number,String,Boolean,undefined,Oject,Function
数组去重的方法,冒泡的方法
冒泡排序:
var arr=[1,2,3,4,7,5];
// 外循环控制轮数length-1
// 冒泡排序的优化
for(var i=0;i<arr.length-1;i++){
// 内循环控制交换次数,越往后交换的次数越少
console.log('交换了');
for(var j=0;j<arr.length-i-1;j++){
if(arr[j]>arr[j+1]){
var temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
console.log(arr);
数组去重:
//定义一个数组
var arr=[1,2,2,5,3,4,3,2,5];
// 由于数组复制的特殊性,存储的是地址而不是具体的数据,
// 更改数组就相当于更改了地址,只要数组里面数值发生改变还是另一个数组的值还是会改变
// 所以这里需要一个新的数组用来存储数据
var result=[];
// 使用循环遍历获取arr里面的值
for(var i=0;i<arr.length;i++){
// 取出result的值
// 需要提前定义一个变量表示当前的状态
var flag=1;
for(var j=0;j<result.length;j++){
if(arr[i]===result[j]){
// 如果相等就判断当前的状态,说明当前已经有数值相同的数值
// 可以结束判断了
flag=0;
break;
}
}
// 必须与上面设置的变量flag在同一作用域,如果作用域等于1表示的是他们没有相等的,就可以输出了
if(flag===1){
result[result.length]=arr[i];
}
}
console.log(result);
for in 和for of的区别
for in 取 key; for of 取 value
for of 只能用于数组遍历,for in还可以用于对象属性的遍历
轮播图实现步骤
主要步骤:
自动轮播
点击小圆圈按钮,显示相应图片
点击左右箭头,实现向前向后轮播图片
实现思路:
1)html+css方面:
图片方面:如果要轮播5张图,那么页面上要写7张图,额外的两张图主要是为了从第一张往前切换和最后一张往后切换的无缝衔接。
布局方面:主要使用绝对定位,分为两层,一层包括图片,一层包括小圆圈按钮和切换箭头
2)js实现:
自动轮播:定时器setInterval和clearInterval
轮播实现原理:
1.首先思考,轮播时候发生的变化:
图片的变化(animate函数) + 小圆圈按钮样式变化(buttonsShow函数)
2.添加事件:
小圆圈按钮事件onclick
左右箭头事件(prev.onclick,next.onclick)
container这个div的onmouseover和onmouseout事件,分别执行play(自动轮播函数)和stop(清除自动轮播定时器)
3.在这上面三个点击事件中都要调用animate函数和buttonsShow函数
H5中webSocket的作用
定义:WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
作用:HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
当你获取 Web Socket 连接后,你可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。
Socket 是传输控制层协议,WebSocket 是应用层协议。
==和===的区别
==会自动进行隐式转换,===不会进行隐式转换
==只比较值,不比较类型,===比较的是值和类型
null和undefined的区别
null是声明了数据,但是值是null的,
undefined是声明未赋值
使用typeof检测null和undefined他们的值是相等的
typeof bar==='object'的风险有哪些
typeof null的值也是object
什么是window对象,什么是document对象
window对象
代表浏览器中的一个打开的窗口或者框架,window对象会在<body>或者<frameset>每次出现时被自动创建,在客户端JavaScript中,Window对象是全局对象,所有的表达式都在当前的环境中计算,要引用当前的窗口不需要特殊的语法,可以把那个窗口属性作为全局变量使用,例如:可以只写document,而不必写window.document。同样可以把窗口的对象方法当做函数来使用,如:只写alert(),而不必写window.alert
window对象实现了核心JavaScript所定义的全局属性和方法。
indow对象的window属性和self属性引用都是他自己。
document对象
代表整个HTML文档,可以用来访问页面中的所有元素 。
每一个载入浏览器的HTML文档都会成为document对象。document对象使我们可以从脚本中对HTML页面中的所有元素进行访问。
document对象是window对象的一部分可以通过window.document属性对其进行访问
HTMLDocument接口进行了扩展,定义HTML专用的属性和方法,很多属性和方法都是HTMLCollection对象,其中保存了对锚、表单、链接以及其他可脚本元素的引用。
创建对象的方式
1)简单对象的创建:使用字面量的方式创建{}
2)使用无参的构造函数创建
function Person(){
}
var personOne=new Person();//定义一个 function,如果有 new关键字去"实例化",那
么该 function可以看作是一个类
personOne.name="dylan";
personOne.hobby="coding";
personOne.work=function(){
alert(personOne.name+" is coding now...");
}
personOne.work();
3)使用有参的构造函数实现:
function Pet(name,age,hobby){
this.name=name;//this 作用域:当前对象
this.age=age;
this.hobby=hobby;
this.eat=function(){
alert("我叫"+this.name+",我喜欢"+this.hobby+",也是个吃货");
}
}
var maidou =new Pet("麦兜",5,"睡觉");//实例化/创建对象
maidou.eat();//调用eat 方法(函数)
4)使用工厂方式创建
function createPerson(name, age, job)
{
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function()
{
alert(this.name);
};
return o;
}
var person1 = createPerson("Nicholas", 29, "Software Engineer");
var person2 = createPerson("Greg", 27, "Doctor");
5)使用原型模式:
function Person(){ }
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person(); person1.sayName(); //"Nicholas"
var person2 = new Person();
person2.sayName(); //"Nicholas"
alert(person1.sayName == person2.sayName); //true
6)组合使用构造函数模式和原型模式
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.friends = ["Shelby", "Court"]; }
Person.prototype = {
constructor : Person,
sayName : function(){
alert(this.name);
}
}
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");
person1.friends.push("Van");
alert(person1.friends); //"Shelby,Count,Van" alert(person2.friends); //"Shelby,Count"
alert(person1.friends === person2.friends); //false
alert(person1.sayName === person2.sayName); //true
7)寄生构造函数模式:
function Person(name, age, job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
};
return o;
}
var friend = new Person("Nicholas", 29, "Software Engineer");
friend.sayName(); //"Nicholas"
箭头函数和普通函数的区别
1)写法上:
箭头函数:
let fun = () => {
console.log('lalalala');
}
普通函数:
function fun() {
console.log('lalla');
}
箭头函数相当于匿名函数,并且简化了函数定义。箭头函数有两种格式,一种只包含一个表达式,连{ ... }和return都省略掉了。还有一种可以包含多条语句,这时候就不能省略{ ... }和return。
2)箭头函数是匿名函数,不能作为构造函数,不能使用new
3)箭头函数不绑定arguments,取而代之的是reset参数...解决
4)箭头函数不绑定this,会被捕获其所在的上下文的this值,作为自己的this值
5)箭头函数通过call或apply方法调用一个函数时,只传入一个参数,对this没有影响
6)箭头函数没有原型属性
7)箭头函数不能当generator函数,不能用yield关键字
用set数据结构的好处
ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
Set本身是一个构造函数,用来生成 Set 数据结构。
好处:
1)向 Set 加入值的时候,不会发生类型转换
2)不会出现重复的值
for循环可以使用什么替代(reduce)
1)forEach(function(currentValue,index,arr))
2)map():map()方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值
3)filter():fliter()方法创建一个新数组,新数组中的元素是通过制定数组中复合条件的所有元素,主要用于筛选数组
4)some():some()方法用于检测数组中的元素是否满足指定条件,通俗点查找数组中是否有满足的条件的元素
5)every():every方法测试一个数组内的所有元素是否都蒙通过某个指定函数的测试,他返回的是一个boolean值
遍历对象的方式有哪些?
方法一:
使用for in 遍历对象
const obj = {
id:1,
name:'zhangsan',
age:18
}
for(let key in obj){
console.log(key + '---' + obj[key])
}
方法二:
1)Object.keys(obj)
2)Object.values(obj)
参数 obj:要返回其枚举自身属性的对象
const obj = {
    id:1,
    name:'zhangsan',
    age:18
}
console.log(Object.keys(obj))//['id','name','age']输出数组形式的属性名
console.log(Object.values(obj))//['1','zhangsan','18']输出数组形式的属性值
方法三:
使用Object.getOwnPropertyNames(obj)
遍历一个数组,包含对象自身的所有属性(包含不可枚举属性),遍历可以获取key和value值
const obj = {
id:1,
name:'zhangsan',
age:18
}
Object.getOwnPropertyNames(obj).forEach(function(key){
console.log(key+ '---'+obj[key])
})
for in能否遍历出原型对象?
for in 可以遍历原型链上的扩展属性,object.keys()只遍历自身属性
区别:使用for in遍历对象的属性时,原型链上的所有属性都被访问
Object.prototype.say="cgl"; // 修改Object.prototype
var person ={ age: 18 };
for (var key in person) {
console.log(key, person[key]);
//这里用person.key得不到对象key的值,用person[key] 或者 eval("person."+key);
//eval()功能很强大,可以计算字符串
}
//结果: age 18
say cgl
Object.keys() 方法会返回一个由给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for...in 循环遍历该对象时返回的顺序一致 (两者的主要区别是 一个 for-in 循环还会枚举其原型链上的属性)。返回值是这个对象的所有可枚举属性组成的字符串数组。
写一个函数判断字符串回文
回文字符串:若一个字符串的正序和倒序相同,称其为回文字符串,现在给定一个字符串,使用递归的方式判断他是否是字符串回文
function palindRome(str) {
var len = str.length;
var str1 = "";
for (var i = len - 1; i >= 0; i--) {
str1 += str[i];
}
console.log(str1 == str)
}
palindRome("abcba");//true
palindRome("abcbac");//false
将多个对象合并成一个对象
方法一:
Object.assign()方法用于将所有枚举属性的值从一个或者多个源对象赋值到目标对象的,他将返回目标对象,并且源对象也会被修改
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target);
// expected output: Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget);
// expected output: Object { a: 1, b: 4, c: 5 }
注意:如果目标对象中属性具有相同的件,则属性会被源对象的属性覆盖,后面的源对象将类似的覆盖前面的源对象的属性,支持多个对象的合并,如果不行修改目标对象,可以将目标对象改成{}
方法二:
使用循环遍历的方式拷贝对象
var obj1={name:'张三'};
var obj2={age:18};
for(var key in obj2){
if(obj2.hasOwnProperty(key)===true){
obj1[key]=obj2[key];
}
}
方法三:
在jQuery中可以使用$.extend() 函数用于将一个或多个对象的内容合并到目标对象。
注意:
1. 如果只为$.extend()指定了一个参数,则意味着参数target被省略。此时,target就是jQuery对象本身。通过这种方式,我们可以为全局对象jQuery添加新的函数。
2. 如果多个对象具有相同的属性,则后者会覆盖前者的属性值。
$.extend( [deep ], target, object1 [, objectN ] )
jQuery事件中on,bind,live,delegate的区别
区别:
1)on不仅仅作用于当前绑定元素,对于未来有脚本语言创建的元素也会有同样的作用,也就是他可以进行事件委托,但是bind不行
2)on事件绑定在父元素身上
3)bind事件绑定的是自己身上
移除:如果要移除on事件,请使用的是off()
什么是闭包,举例说明
闭包是一个作用域内访问另一个作用域私有变量的函数称为闭包函数
function init() {
var name = "Mozilla"; // name 是一个被 init 创建的局部变量
function displayName() { // displayName() 是内部函数,一个闭包
alert(name); // 使用了父函数中声明的变量
}
displayName();
}
//内部函数访问外部函数的私有变量
init();
闭包的缺点:闭包会造成内存泄漏,会对性能有一定的影响
闭包的优点:因为他定义的私有变量,所以对于全局变量而言这个函数使用更加安全,同时他也延长了作用域的使用范围
http中的content-type的作用
content-type决定如何展示返回的消息体内容;
http中的cache-control了解吗?有什么作用?
cache-control:缓存控制
在http协议中,控制缓存开关的字段有两个:Pragma和Cache-Control
1)符合缓存策略时,服务器不会发送新的资源,但不是说客户端和服务器就没有会话了,客户端还是会发请求到服务器的。
2)Cache-Control除了在响应中使用,在请求中也可以使用。
3)同时在Response Headers中也能到Cache-Control字段,它的值是must-revalidate,这是服务端设置的。
4)在请求和响应中都可以使用该字段,但是该字段在设置的时候也有很多的可选值,最常用的是no-cache还有no-stroe,在使用的时候这些值可以有结合,多个值冲突时,也是有优先级的,而no-store优先级最高
对this的理解
this在构造函数中,指向的是实例对象
this在事件处理程序中指向的是事件源
this在定时器中指向的window
this在普通函数指向的也是window
this的指向是可以更改的可以使用call,apply,bind更改this指向
this在箭头函数中,指向定义区域的this
表单验证传输的是什么数据?明文还是暗文==加密?如何加密?是每一传输数据,都是加密之后才传输的吗?
GET是从服务器上请求数据,POST 是发送数据到服务器。事实上,GET方法是把数 据参数队列(query string)加到一个URL上,值和表单是一一对应的。
比如说, name=John。在队列里,值和表单用一个&符号分开,空格用+号替换,特殊的符号转换 成十六进制的代码。
因为这一队列在 URL里边,这样队列的参数就能看得到,可以被记录 下来,或更改。通常GET 方法还限制字符的大小(大概是 256 字节 )。
事实上POST 方法可以没有时间限制的传递数据到服务器,用户在浏览器端是看不到 这一过程的,所以 POST方法比较适合用于发送一个保密的(比如信用 卡号)或者比较大 量的数据到服务器。
区别:
Post 是允许传输大量数据的方法,而 Get 方法会将所要传输的数据附在网址后面,然 后一起送达服务器,因此传送的数据量就会受到限制,但是执行效率却比 Post 方法好。
总结:
1、get 方式的安全性较Post 方式要差些,包含机密信息的话,建议用 Post 数据提交 方式; 2、在做数据查询时,建议用 Get 方式;而在做数据添加、修改或删除时,建议用Post 方式; 所以: 表达如果是向服务器传输数据(如帐号密码等)都是加密数据(post),如果只是单单想要 从服务器获得数据或者传输的数据并不重要, 可以直接使用明文方式传输( get )
如何实现跨域?
七种跨域实现方案:
参考地址博客:juejin.cn/post/684490…
什么是原型链
Javascript 是面向对象的,每个实例对象都有一个__proto_属性,该属性指向它原 型对象,这个实例对象的构造函数有一个原型属性 prototype,
与实例的__proto__属性指 向同一个对象。当一个对象在查找一个属性的时,自身没有就会根据__proto__ 向它的原型 进行查找,如果都没有,则向它的原型的原型继续查找,直到查到 Object.prototype._proto_为null,这样也就形成了原型链。
图示原型链:

实现继承的方法有哪些?
(1)借用构造函数。也叫伪造对象或经典继承。 思路:在子类构造函数的内部调用超类型构造函数。可以通过使用 apply()和call()方法 在新创建的对象上执行构造函数。 缺点:方法都在构造函数中定义,函数的复用就无从谈起。在超类型的原型中定义的方 法,对子类而言也是不可见的,结果所有的类型都只能使用构造函数模式。

(2)组合继承。也叫伪经典继承。指的是将原型链和借用构造函数的技术组合到一起, 从而发挥二者之长。 思路:使用原型链实现对原型属性属性和方法的继承,通过借用构造函数来实现实例属 性的继承。 优点:既通过在原型上定义方法实现了函数复用,又能保证每一个实例都有它自己的数 组。 组合继承避免了原型链和借用构造函数的缺陷,融合了他们的优点,成为 JavaScript 中常用的继承模式
(3)原型链继承。 思路:借助原型可以基于已有的对象创建对象,同时还不必因此创建自定义类型。 在object()函数内部,先创建一个临时的构造函数,然后将传入的对象作为这个构造函 数的原型,最后返回了这个临时类型的一个新实例。
(4)寄生式继承。 思路:创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最 后再像真的是它做了所有的工作一样返回对象 缺点:使用寄生式继承来为对象添加函数,会由于不能做到函数复用二降低效率,这一 点和构造函数模式类似。
(5)寄生组合式继承。是JavaScript 最常用的继承模式。 思路:通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。 本质上,就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。 开发人员普遍认为寄生组合式继承时引用类型最理想的继承范式。 extend()方法才用了这样的方式。
ajax的请求数据步骤是什么?传输数据是用get还是post?
使用get方式发送ajax请求
// -------请求发送部分-------
// 1.初始化操作 创建XMLHttpRequest()
var xhr=new XMLHttpRequest();
// console.log(xhr.readyState);
// 2.建立连接:调用xhr的open方法
// 参数1:请求方式
// 参数2:请求的接口地址
// 2.1需要在url后自己拼接get请求的参数
// 形式为urlencode:'名1=值1&名2=值2'
xhr.open('get',' http://localhost:3005/common/get?username=jack&userAge=18');
// console.log(xhr.readyState);
// 3.发送请求,调用xhr.send();
xhr.send();
// -------响应处理部分--------
// 4.通过事件来检测ajax的进行状态
// readystate是xhr的属性,用来表示ajax操作的状态
// 属性值是数值类型
// 0 初始化阶段
// 1 建立了连接
// 2 已经发送
// 3 响应的数据在下载中
// 4 下载完成(这个阶段才能使用响应的数据)
xhr.onreadystatechange=function(){
// console.log(xhr.readyState,'事件内部的取值');
// 确定readyState为4的时候,获取响应信息
if(xhr.readyState===4){
console.log(JSON.parse(xhr.responseText));
}
}
使用post方式发送ajax请求的:
// 创建异步对象
var xhr=new XMLHttpRequest();
// post参数不要写在url后面
// 参数1:请求方式type 参数2 请求的接口地址url
// 注意 post请求参数不要书写在url后面
xhr.open('post',' http://localhost:3005/common/post');
// 设置请求头
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
// 发送请求 调用send()
// 注意:post请求参数需要传入到send的参数中
// 参数的格式也是urlencoded
// 注意 由于post请求参数不是在url中传递的,需要服务端发送额外的一些数据
// 这是数据称为request header请求头
xhr.send('username=jack&userAge=18&userGender=男');
// 进行响应的相关处理
xhr.onreadystatechange=function(){
if(xhr.readyState===4){
if(xhr.getResponseHeader('Content-Type').indexOf('json')!==-1){
console.log(JSON.parse(xhr.responseText));
}else{
console.log(xhr.responseText);
}
}
}
ajax的原理是什么
ajax的原理简单的说就是通过XmlHttpRequest对象来向服务器发送异步请求,从服务器获取数据,然后使用JavaScript来操作DOM而更新页面,这其中最关键的一步就是从服务器获得请求数据
1.创建XmlHttpRequest对象
2建立连接,设置为Get发送xhr.open()
3,发送数据xhr.send()
4.注册回调方法:xmlHttp.onreadystatechange=function(){}
5执行回调函数
ajax的优缺点
1.ajax不支持浏览器back按钮
2安全问题AJAX暴露了与服务器交互的细节
3.对搜索引擎的支持比较弱
4.破坏了程序的异常机制
5不容易调试
输入网址到渲染页面发生了什么?
详细的网络模块知识:
参考博客地址:juejin.cn/post/684490…
DOM常用的节点操作方法
一、创建节点、追加节点
1、createElement(标签名)创建一个元素节点(具体的一个元素)。
2、createTextNode(节点文本内容)创建一个文本节点
3、createDocumentFragment() //创建一个 DOM 片段
4、appendChild(节点)追加一个节点。
二、插入节点
1、appendChild(节点)也是一种插入节点的方式,还可以添加已经存在的元素,会将其
元素从原来的位置移到新的位置。
2、insertBefore(a,b)是参照节点,意思是 a节点会插入 b节点的前面。
三、删除、移除节点
1、removeChild(节点) 删除一个节点,用于移除删除一个参数(节点)。其返回的被移除
的节点,被移除的节点仍在文档中,只是文档中已没有其位置了。
四、复制节点
cloneNode() 方法,用于复制节点, 接受一个布尔值参数, true 表示深复制(复制节点
及其所有子节点), false 表示浅复制(复制节点本身,不复制子节点)
五、替换节点
1、replaceChild(插入的节点,被替换的节点) ,用于替换节点,接受两个参数,第一参数
是要插入的节点,第二个是要被替换的节点。返回的是被替换的节点。
六、查找节点
1、getElementsByTagName() //通过标签名称
2、getElementsByName() //通过元素的Name 属性的值(IE容错能力较强,会得到一
个数组,其中包括 id等于 name值的)
3、getElementById() //通过元素 Id,唯一性
事件委托机制,这样做的好处是什么?
事件委托,就是某个事件本来该自己干的,但是自己不干,交给别人来干。就叫事件委 托。打个比方:一个button 对象,本来自己需要监控自身的点击事件,但是自己不来监控 这个点击事件,让自己的父节点来监控自己的点击事件。 好处: A,提高性能:列如,当有很多 li同时需要注册事件的时候,如果使用传统方法来注册 事件的话,需要给每一个 li 注册事件。然而如果使用委托事件的话,就只需要将事件委托给 该一个元素即可。这样就能提高性能。 B,新添加的元素还会有之前的事件;
谈谈对jQuery的理解
1)JQuery 是继 prototype 之后又一个优秀的 Javascript 库。
2)它是轻量级的js 库 ,它
兼容 CSS3,还兼容各种浏览器(IE 6.0+,FF1.5+,Safari 2.0+,Opera 9.0+), jQuery2.0
及后续版本将不再支持 IE6/7/8 浏览器。
3)jQuery 使用户能更方便地处理 HTML(标准通用
标记语言下的一个应用)、events、实现动画效果,并且方便地为网站提供 AJAX 交互。
4)jQuery还有一个比较大的优势是,它的文档说明很全,而且各种应用也说得很详细,
同时还有许多成熟的插件可供选择。
5)jQuery 能够使用户的 html页面保持代码和 html 内容
分离,也就是说,不用再在 html里面插入一堆 js 来调用命令了,只需要定义 id即可。
6)jQuery 是一个兼容多浏览器的 javascript 库,核心理念是write less,do more(写
得更少,做得更多)。
7)jQuery是免费、开源的,使用 MIT 许可协议。jQuery 的语法设
计可以使开发更加便捷,例如操作文档对象、选择 DOM 元素、制作动画效果、事件处理、
使用 Ajax 以及其他功能。
8)除此以外,jQuery 提供 API让开发者编写插件。其模块化的使
用方式使开发者可以很轻松的开发出功能强大的静态或动态网页。
关于jQuery内部封装原理:
1)为了全局变量不被污染,所以这里直接使用一个自调用函数将函数中的代码进行包裹
2)通过对象的方式,把函数变成是对象的方法,然后对外暴露这个属性名
3)jQuery的构造函数是init,通过把jQuery中init的原型对象和jQuery的原型对象设置一致
4)由于里面的原型对象一致,所以这里就可以让开发者直接在构造函数的原型对象上绑定方法,这样就可以编写插件了
call 和 apply还有bind的区别
相同点:他们三个都可以改变this指向
不同点:call和apply会调用函数,bind不会调用函数
call的参数是变量,apply的第二个参数是一个数组,
原生的jS的window.onload和jQuery中的$(document).ready(function{}),$(function(){})有什么不同?
1.执行时间 window.onload必须等到页面内包括图片的所有元素加载完毕后才能执行。 $(document).ready()是 DOM 结构绘制完毕后就执行,不必等到加载完毕。
2.编写个数不同 window.onload不能同时编写多个,如果有多个 window.onload 方法,只会执 行一个 $(document).ready()可以同时编写多个,并且都可以得到执行
3.简化写法 window.onload没有简化写法 $(document).ready(function(){})可以简写成$(function(){});
在js的计时器运行原理是怎样的,为什么可以出发计时效果,计时器是多线程的吗?
1. javascript引擎只有一个线程,强迫异步事件排队等待被执行。
2. setTimeout 和setInterval 本质上不同的地方是他们如何执行异步代码的。
3. 如果一个定时器正在执行的时候被阻塞了,那么它将会被推迟到下一个可能的执 行 点,这既是使得延迟时间有可能会超过声明定时器时设置的值。
4.Interval 如果有足够的时间来执行(大于制定的延迟),那么它将会无延迟的一个紧 接着一个执行。
原理: 计时器通过设定一定的时间段(毫秒)来异步的执行一段代码。因为 Javascript 是一 个单线程语言,计时器提供了一种绕过这种语言限制来执行代码的能力。
总结: 计时器是单线程的, 需要等待上一个执行完, 如果上一个没有执行完, 下一个需要 延迟执行, 直到上一个执行完。
JavaScript中的作用域,预解析与变量声明提升?
作用域:
作用域就是变量的有效范围
分类:
ES6之前:
函数作用域:只有函数能够划分变量的作用域,这种作用域的规则就叫函数作用域。 如果在函数内访问一个变量,优先找局部变量和形参,如果没有找到,去定义该函数的环境 中查找,直到全局为止。
ES6之后:
块级作用域:凡是代码块就可以划分变量的作用域,这种作用域的规则就叫块级作用域。
预解析:
在代码整体执行之前,先解析一部分。 预解析之后,代码才会从上往下依次整体执行,但是预解析执行过的代码不会 重复执行。 js预解析干了什么事:js 中预解析会把声明部分的代码预先执行。 声明相关的代码可以分为两部分:
1、 变量声明 通过 var关键字定义的变量。
2、函数声明 通过 function关键字声明的函数
预解析时
1)如果遇到重复的变量声明,那么忽略。 2)预解析时如果遇到重复的函数声明,保留后面的函数。 3)预解析时如果遇到变量与函数重名的情况,保留函数。
变量声明的特点:
使用 var关键字定义的变量,被称为变量声明; 函数声明提升的特点是,在函数声明的前面,可以调用这个函数。
创建函数的方式
第一种(函数声明):
function sum1(num1,num2){
return num1+num2;
}
第二种(函数表达式)
var sum2 = function(num1,num2){
return num1+num2;
}
第三种(函数对象方式)
var sum3 = new Function("num1","num2","return num1+num2");
第四种(箭头函数)
()=>{}
对于事件流的理解
事件流也就是事件的三个阶段:
事件的捕获阶段
事件的目标阶段
事件的冒泡阶段
IE和DOM事件流的区别
1.执行顺序不一样
2参数不一样
3事件加不加on
4this指向问题
注意:
(1)在IE9之前:,attachEvent('onclick'),detachEvent('onclick')
(2)IE9开始跟DOM事件流式一样的,都是addEventListener
比较attachEvent和addEventListener
1)attachEvent只支持事件冒泡 addEventListener既支持事件冒泡,也支持事件捕获
2)参数:attachEvent事件类型需要加on前缀,addEventListener事件类型不需要加on前缀
3)如果使用attachEvent对一个元素的目标阶段绑定了多次事件,那么会按照绑定顺序的相反顺序进行触发
4)如果使用了addEventListener对一个元素的目标阶段绑定了多次事件,那么会按照绑定顺序进行触发
如何阻止事件冒泡和默认事件?
阻止事件冒泡:
IE9以上 谷歌 e.stopPropagation()
IE9以下 event.cancelBubble=true
阻止默认事件:
IE9之前:window.event.returnValue=false
IE9之后e.preventDefault()
面向对象和类的区别?
在 js 中没有类, 所以在js 中所谓的 类 就是构造函数, 对象就是由构造函数创建
出来的实例对象。面向对象就是使用面向对象的方式处理问题, 面向对象是对面向过程进
行封装。
面向对象的三大特性:
继承性
封装性
多态性
怎么判断一个JavaScript变量是array还是object?
1、如果你只是用 typeof来检查该变量,不论是array 还是 object,都将返回‘object'。 此问题的一个可行的答案是检查该变量是不是 object,并且检查该变量是否有数字长度(当 为空 array时长度也可能为 0)。 然而,参数对象【arguments object】(传给制定函数的所有参数),也可能会适用于上 述方法,技术上来说,参数对象并不是一个array。 此外,当一个对象有a.length 属性的时候,这个方法也不成立
2.类型检测 使用instanceof
3.使用函数isArray这个函数
4.使用constructor判断
5.使用Object.prototype.toString.call()
解释jsonp的原理,以及为什么不是真正的ajax
jsonp的原理:动态创建 script 标签,回调函数
为什么不是真正的ajax?
ajax和jsonp 这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个 url,然后把服务器返回的数据进行处理,因此 jquery 和 ext 等框架都把 jsonp作为 ajax 的一种形式进行了封装;
2、但 ajax和 jsonp其实本质上是不同的东西。ajax的核心是通过 XmlHttpRequest 获取非本页内容,而 jsonp的核心则是动态添加<script>标签来调用服务器提供的js 脚本。
3、所以说,其实ajax 与jsonp的区别不在于是否跨域,ajax通过服务端代理一样可 以实现跨域,jsonp本身也不排斥同域的数据的获取。
4、还有就是,jsonp是一种方式或者说非强制性协议,如同 ajax一样,它也不一定非 要用 json格式来传递数据,如果你愿意,字符串都行,只不过这样不利于用 jsonp提供公 开服务。 总而言之,jsonp不是 ajax 的一个特例,哪怕 jquery等巨头把 jsonp封装进了 ajax, 也不能改变着一点!
javascript中的垃圾回收机制
在Javascript 中,如果一个对象不再被引用,那么这个对象就会被GC 回收。如 果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。 因为函数 a被b引用,b又被 a外的 c引用,这就是为什么 函数 a 执行后不会被回收的原 因。
事件绑定和普通事件有什么区别?
事件绑定是指把事件注册到具体的DOM 元素之上,普通事件指的是可以用来注册的事件
事件绑定例子:
DOM 元素.addEventListener( 事件类型,事件处理函数)
普通事件例子: DOM 元素.事件类型 = function(){事件处理函数}
对于事件绑定来说,同一个 DOM 元素上面绑定同样的事件类型时,可以绑定多个事件
处理函数,实际解决了多人开发情况下造成的时间处理覆盖的情况(污染),而如果使用普
通事件来解决这个问题的时候会造成后写的代码将前写的代码进行了重写操作,造成环境污
染。
实际开发的时候可以视情况而定,来选择绑定事件的方式。
JavaScript中的callee和caller的作用?
caller是返回一个对函数的引用,该函数调用了当前函数;
callee 是返回正在被执行的function函数,也就是所指定的 function 对象的正文。
prop和attr的区别?
对于HTML本身就带有的固有属性,在处理时使用prop方法
对于HTML元素我们自定义的DOM属性,在处理时,使用attr方法
new操作符干了什么?
1.创建了一个实例对象
2.给新创建的对象绑定了this指向
3.调用了构造函数
4.返回了构造函数
js中深拷贝和浅拷贝的区别
深拷贝只复制某个对象的指针,而不复制对象本身,新旧对象韩式共享同一块内存
深拷贝会另外创造一个一模一样的对象,新对象和原对象不共享内存,修改新对象不会修改到原对象
深拷贝的方法:
1.递归拷贝
2.使用Object.create()方法
3.jquer中的$.extend也介意实现
4.函数库中lodash,也有提供cloneDeep用来实现
什么是回调地狱,怎么解决回调地狱?
由于回调函数是异步的,每一层的回调函数都需要依赖上一层的回调执行完,所以形成了层层嵌套的关系最终形成了回调地狱,例如说:定时器中再写定时器,这样就形成了回调地狱
解决回调地狱:
1 避免函数的嵌套
2模块化开发
3使用promise解决
对于ES6中promise的理解
Promise和async还有await详解参考博客地址:
对json的了解
json指的是js对象的表示法
1.轻量级的数据交互格式
2.可以形成复杂的嵌套格式
3解析非常方便
4易于读写,占用带宽小
什么是内存泄漏,哪些常见的操作会造成内存泄漏?
内存泄漏指的是一块被分配的内存既不能使用,也不能回收,直到浏览器进程结束,在c++中,因为是手动管理内存,内存泄漏是经常出现的事情,
而现在流行的c#和Java等语言采用了自动垃圾回收方法管理内存,正常使用的情况下几乎不会发生内存泄漏,浏览器也是采用自动垃圾回收方法管理内存,但由于浏览器垃圾回收方法有bug,会产生内存泄漏
常见的内存泄漏的操作
1.全局变量引起的内存泄漏
2闭包引起的内存泄漏
3dom清空或删除时,事件未清除导致的内存泄漏
简述readonly和disabled的区别
readOnly和Disabled的作用是使用户不能够更改表单域中的内容
区别:
1)readOnly只针对input和textarea有效,而disabled对所有表单元素有效
2)在表单元素使用了disabled之后,我们将表单以post或者get的方式提交的话,这个元素的值不会被传递出去,而readOnly会将该值传递出去
$(this)和this的区别是什么?
$(this)返回的是一个jQuery对象,你可以对他调用多个jQuery方法,比如用text()获取文本,用val()获取值等等,
而this代表当前元素,他是JavaScript关键词中的一个,表示上下文的当前DOM元素
jQuery对象和DOM对象的转换?
jQuery转DOM对象:
jQuery对象是一个数组对象,可以通过[index]的方式得到对应的DOM对象,还可以通过get[index]去得到相应的DOM对象,DOM对象转jQuery对象:$(DOM对象)
jQuery中$.extend和$.fn.extend的区别
$.extend
用来进行对象拷贝功能的使用
参数1:最终都被合并到那个对象中
后续参数都被合并到参数1中
$.extend(obj3,obj2,obj);
基于浅拷贝功能,添加最前面的可选参数1为true,用来进行深拷贝操作
$.extend(true,obj3,obj2,obj);
浅拷贝
参数1:最终都被合并到那个对象中
后续参数都被合并到参数1中
$.extend(obj3,obj2,obj);
深拷贝
基于浅拷贝功能,添加最前面的可选参数1为true,用来进行深拷贝操作
$.extend(true,obj3,obj2,obj);
对象的合并
var obj3=$.extend(true,{},obj2,obj);
合并功能与参数1true无关
$.fn.extend
jQuery提供了顶级对象$,jQuery 值是一个函数
任意函数都具有prototype属性,$也用$.prototype
jQuery为了用户方便操作,给$.prototype设置别名为$.fn
总结:
$.extend用来扩展jQuery对象本身
$.fn.extend用来扩展jQuery实例
jQuery.fn的init返回的this指的是很么对象?为什么要返回this?
this执行init构造函数本身,其实就是jQuery实例对象,返回this是为了实现jQuery的链式编程
jQuery中ajax的请求步骤

ajax出现错误怎么调式
jQuery使我们在开发ajax应用程序的时候提高了效率,减少了许多兼容性问题,我们在ajax项目中,遇到ajax异步获取数据出错怎么办,我们可以通过捕捉error事件来获取出错的信息,发送error可能有下面两种问题引起的,或者是其他的程序问题
web应用从服务器主动推送Data到客户端有哪些方式
1.html5的webSoclet
2.webSocket通过flash
3xhr长时间连接
4xhr Multipart Streaming
5不可见的iframe
script标签的长时间连接
js延迟加载的方式有哪些?
defer 属性
async属性
动态创建DOM方式
使用jQuery的getScript方法
使用setTimeout延迟方法
让js最后加载
你如何优化自己的代码
1)代码重用
2)避免使用过多的全局变量
3)拆分函数避免函数过于臃肿:单一职责原则
4)将面向过程的变成方式改为使用面向对象编程
5)适当的注释,尤其是一些复杂的业务逻辑或者是计算逻辑,都应该写出这个业务逻辑的具体过程
6)内存管理,尤其是闭包中的变量释放
前端开发的优化问题
参考博客: