文章目录
-
-
- 1:Js基本数据类型有哪些
- 2:Ajax如何使用,常见HTTP状态码
- 3:js中的变量提升
- 4:判断一个数据是NaN
- 5:null和undefined区别
- 6:object.is()和`===`、`==` 的区别?
- 7:闭包是什么,有什么特性,
- 8:事件委托是什么?如何确定事件源
- 9:本地存储与cookie的区别
- 10:let,const,var的区别
- 11:ES6的新特性
- 12:数组的方法
- 13:new一个箭头函数会怎样
- 14:new操作符的实现步骤
- 15:构造函数和普通函数的区别
- 16:箭头函数
- 17:逆运算符的使用场景
- 18:原型,原型链,继承
- 19:Promise的理解
- 20:**Promise**在哪里使用过
- 21:js中call()和apply()的区别
- 22:跨域/同源策略
- 23:this的指向
- 24:什么是jsonp工作原理,他为什么不是ajax
- 25:jsonp和json的区别
- 26:深浅拷贝是什么如何实现?
- 27:请输出三种减少页面加载时间的方式
- 28:JavaScript 类数组对象的定义?
- 29:为什么函数的 arguments 参数是类数组
- 29:为什么函数的 arguments 参数是类数组
-
1:Js基本数据类型有哪些
String,number,boolean,undefined,null
“”,0, null,undefined, NaN, false 会自动转换为false
其中数据的检测类型可以划分为
-
typeof
console.log(typeof function(){ }); // function console.log(typeof []); // object
-
instanceof:检测机制是通过判断其原型对象上是否有该类的原型
【判断对象】
console.log(2 instanceof Number); // false console.log([] instanceof Array); // true console.log(function(){ } instanceof Function);// true
-
constructor
console.log((2).constructor == Number); // true console.log((true).constructor == Boolean); // true console.log(('str').constructor == String); // true console.log(([]).constructor == Array); // true console.log((function() { }).constructor == Function); // true console.log(({ }).constructor == Object); // true
2:Ajax如何使用,常见HTTP状态码
Ajax是一种异步交互技术,可以在不重新加载整个页面的情况下,对网页进行局部的加载更新
Ajax的优点是:
-
对用户的操作作出及时的反应,
-
在不中断用户操作的情况下和web服务器进行交互
-
局部更新相对于整个页面的更新可以降低网络的流量
Ajax的Get请求是:
Let xhr=new xmlhttprequest() 0
//open 可以设置请求的方式(请求方式,地址,是否异步)
Xhr.open("get”,”ajax.php?username="+值,true) 1
Xhr.send()
Xhr.onreadystagechange=function(){
3
If(xhr.status==200&&xhr.readystate==4){
Console.log(xhr.responseText)
} }
Ajax的Post请求是:
Let xhr=new xmlhttprequest() 0
//open 可以设置请求的方式(请求方式,地址,是否异步)
Xhr.open("post”,”ajax.php") 1
Xhr.send("username"+值)
//请求头
Xhr.setRequestHeader(“ Content-type”,”application”)
Xhr.onreadystagechange=function(){
3
If(xhr.status==200&&xhr.readystate==4){
Console.log(xhr.responseText)
} }
Ajax的常用转态码:
- 200:处理请求成功
- 204:请求成功,但是没有返回值
- 301:请求的页面已经被永久的移除了
- 302:请求的页面,被临时移除了
- 400:不理解请求的语法
- 403:服务器拒绝请求
- 404:服务器找不到请求的url
- 500:服务器有错误,无法完成请求
- 503:服务器无法使用
3:js中的变量提升
变量提升是:无论是在函数的何种位置声明变量,该变量都不会报错函数的声明会被提前到函数的顶部,在全局变量中也是一样的
为什么会出现变量提升:
主要得益于js脚本语言在浏览器中的运行机制,js的运行会分为两部分
(1):代码的解析过程:js会在代码进行解析的时候,现将即将使用到的所有的变量进行提前赋值,赋值为undefined,同时也会将即将执行的函数进行提前声明,这些都会在全局上下文中执行,在函数提前声明之前,也会创建一个函数的上下文,函数的上下文会包括(this,参数,argument)
(2):代码的执行过程:按照执行顺序进行依次执行
4:判断一个数据是NaN
- NaN!= NaN结果返回true表明他是一个NaN
- 采用es6中的Object.is(a, NaN) 结果返回true表明他是一个NaN
- 通过isNaN( ), 结果返回true表明他是一个NaN
5:null和undefined区别
Undefined:常用来表示一个定义了但是没有赋值的变量,Undefined不是一个保留关键字
Null:常用来表示一个还没有存在的对象
判断:
两者在不严格等于的情况下是相等的
但是在严格等于的情况下是不相等的
采用typeof检测的时候,undefined返回undefined,null返回的是object
转换为数字的时候,undefined会返回NaN,null会返回0
Undefined的值出现有四种情况:
-
数据定义了但是没有赋值
-
数组中空出来的值
-
对象没有相应的方法和属性
-
函数没有返回值的时候
6:object.is()和===
、==
的区别?
双等号进行相等判断时,如果两边的类型不一致,则会进行强制类型转化后再进行比较。
三等号进行相等判断时,如果两边的类型不一致时,不会做强制类型准换,直接返回 false
使用 Object.is 来进行相等判断时,一般情况下和三等号的判断相同,它处理了一些特殊的情况,比如 -0 和 +0 不再相等,两个 NaN 认定为是相等的。
7:闭包是什么,有什么特性,
闭包就是能够读取其他函数内部变量的函数。闭包函数的使用必须使用var关键字声明变量
闭包的缺点:容易造成内存泄漏
闭包的优点:可以内部变量访问外部变量,可以永久的保存某些变量
闭包的造成是:浏览器中自带的垃圾回收机制
垃圾回收机制:在 Javascript 中,如果⼀个对象不再被引⽤,那么这个对象就会被垃圾回收机制回收。如果两个对象互相引⽤,⽽不再 被第 3 者所引⽤,那么这两个互相引⽤的对象也会被回收
垃圾回收机制的方法:1。标记清除,2。引用计数
8:事件委托是什么?如何确定事件源
事件委托就是利用事件冒泡,只制定一个事件处理程序,就可以管理某一类型的所有事件。
事件委托的好处:
将某一个事件加在父元素身上,提高程序的执行效率
要是动态创建的元素,会给新创建好的元素提前绑定触发事件
事件委托的方法:
父元素.事件=function(evt){
//获取事件的真正操作源
Var e = evt || event;
//真正的操作元素
var target = e.srcElement || e.target;
}
//确定事件源采用target.tagName
9:本地存储与cookie的区别
特性 | Cookie | localStorage | sessionStorage |
---|---|---|---|
数据的生命期 | 一般由服务器生成,可设置失效时间 | 除非被清除,否则永久保存 | 仅在当前会话下有效 |
存放数据大小 | 4K左右 | 一般为5MB | 一般为5MB |
与服务器端通信 | 跟随http一起进行发送的,所以会浪费一部分带宽 | 仅在客户端中保存,不参与和服务器的通信 | 仅在客户端中保存,不参与和服务器的通信 |
易用性 | 需要程序员自己封装,源生的Cookie接口不友好 | 源生接口可以接受,亦可再次封装来对Object和Array有更好的支持 | 源生接口可以接受,亦可再次封装来对Object和Array有更好的支持 |
localstroage的相关API
a : localstroage.getitem(key)
b : localstroage.setitem(key,value)
c : localstroage.removeitem(key)删除key值对应的
d : localstroage.clear():删除所有的键值对
10:let,const,var的区别
-
let的基本用法:
1:块级作用域(let,const)
2:暂时性死区
Let a=123; { Console.log(a) a=456 } Console.log(a)
3:不存在变量提升
4:不允许重复声明
5:let和const声明的变量不会成为全局对象的属性
-
const的值可以变吗
const保证的并不是变量的值不得改动,而是变量指向的那个内存地址不能改动
基本数据类型:值就保存在变量指向的那个内存地址,因此等同于常量
引用数据类型:变量指向数据的内存地址,保存的只是一个指针,const只能保证这个指针是固定不变的,至于它指向的数据结构是不是可变的,就完全不能控制了
-
var声明的变量
var声明的变量会挂载在window上,而let和const声明的变量不会:
11:ES6的新特性
-
let,const
-
模板字符串``,使用
内容+$(变量)
-
箭头函数
-
对象解构
解构对象:let {name,age,sex}=[name:”li”,age:5,sex:”女”]
解构数组:let {x,y,a }=[1,3,5]
-
逆运算符[…obj]
-
for in(不能遍历对象)和for of
-
ES6中的类
12:数组的方法
-
push( I ),从后面添加元素,返回值为添加完后的数组的长度
-
arr.pop( ),从后面删除元素,只能是一个,返回值是删除的元素
-
arr.shift ( ),从前面删除元素,只能删除一个 返回值是删除的元素
-
arr.unshift( I ),从前面添加元素, 返回值是添加完后的数组的长度**
-
arr.splice(索引,位移,添加的元素),删除或者添加元素,删除从i(索引值)开始之后的那个元素共删除(n) 位。返回值是删除元素组成的数组
-
arr.slice(start,end), 左闭右开,切去索引值start到索引值end的数组,不包含end索引的值,返回值是切出来的数组
-
arr.concat( ) 连接两个数组 返回值为连接后的新数组
-
arr.join( ) 将数组转化为字符串
-
str.split( ) ,将字符串转化为数组
-
arr.sort( ) ,将数组进行排序,返回值是排好的数组,默认是按照最左边的数字进行排序,不是按照数字大小排序的
-
arr.reverse() ,将数组反转,返回值是反转后的数组
-
arr.indexof(元素查找数组中某一个元素的下标, 不存在返回-1.存在返回下标
数组的新增API
-
arr.forEach((v,i)=>{}) ,遍历数组,无return 即使有return,也不会返回任何值,并且会影响原来的数组
-
arr.map((v,i)=>{return }),映射数组(遍历数组),有return 返回一个新数组
-
arr.filter((v,i)=>{return}), 过滤数组,返回一个满足要求的数组
13:new一个箭头函数会怎样
箭头函数是ES6中的提出来的,它没有prototype,也没有自己的this指向,更不可以使用arguments参数,所以不能New一个箭头函数。
14:new操作符的实现步骤
- 创建一个空的对象
- 将构造函数的作用域赋值给新new的对象【即就是将对象的-proto-属性指向构造函数的prototypr属性】
- 构造函数中的this指向该对象(也就是通过this为新对象添加属性何方法)
- 返回新的对象
15:构造函数和普通函数的区别
命名规则上:构造函数一般大写,普通函数一般采用驼峰命名法
调用的时候:构造:new fun();普通:fun()
This的指向区别:构造:new出来的 ;普通:谁调用指向谁
16:箭头函数
-
箭头函数书写更加简洁高级,多变
//无参 ()=>{ console.log("haha")} //一个参数 a=>{ console.log("haha")} //多个参数 a,b,c=>{ console.log("haha")} //返回值只有一句话且没有返回值 a,b,c=> void console.log("haha") //有返回值且只有一句话 a,b,c=> return "haha"
-
箭头函数的this问题
箭头函数不会创建自己的this, 所以它没有自己的this
它只会在自己作用域的上一层继承this。
所以箭头函数中this的指向在它定义时已经确定了,之后不会改变。【箭头函数继承来的this指向永远不会改变】
var id="123" var obj={ id:"987" a:function (){ console.log(this.id) } b:()=>{ console.log(this.id) } } obj.a()//987 //方法b是使用箭头函数定义的,这个函数中的this就永远指向它定义时所处的执行环境,(即就是祖父) obj.b()//123
17:逆运算符的使用场景
-
对象:用于取出参数对象中的所有可遍历属性
let obj={ a:1,b:"haha"} let obj2={ ...obj} //注意:要是在逆运算符后面添加自定义属性,要是添加的属性和你元算符的属性同名,就会被覆盖 let obj3={ ...obj,{ a:2,b:"gaga"}}//a:2,b:"gaga"
-
数组
const arr1 = [1, 2]; const arr2 = [...arr1];
18:原型,原型链,继承
**原型:**绝大部分的函数都有⼀个 prototype 属性,这个属性是原型对象⽤来创建新对象实例,而所有被创建的对象都会共享原型对象,因此这些对象便可以访问原型对象的属性。
hasOwnProperty() ⽅法存在于Obejct原型对象中,它便可以被任何对象当做⾃⼰的⽅法使⽤. object.hasOwnProperty( propertyName )可以判断该对象是否有该原型
**原型链:**是每个对象都有 proto 属性,此属性指向该对象的构造函数的原型。对象可以通过 proto 与上游的构造函数的原型对象连接起来,⽽上游的原型对象也有⼀个 proto ,这样就形成了原型链。
**继承:**利用原型中的成员可以被和其相关的对象共享这一特性,可以实现继承,这种实现继承的方式,就叫做原型继承.
19:Promise的理解
romise 是一种解决异步编程的方案,相比回调函数和事件更合理和更强大。从语法上讲,promise是一个对象,从它可以获取异步操作的消息;
对于promise,只要resolve和reject是异步代码
-
三种状态:
1.pending 初始状态也叫等待状态
2.resolve成功状态
3.rejected失败状态;创造promise实例后,它会立即执行。
-
两个特点:
1.Promise对象的状态不受外界影响
2.Promise的状态一旦改变,就不会再变,任何时候都可以得到这个结果,状态不可以逆,
-
解决两个问题
1.回调地狱,代码难以维护
2.promise可以支持多并发的请求,获取并发请求中的数据
-
【promise是解决异步的问题,不能说promise本身是异步的。Promise本身是同步的立即执行函数 】
//【先同步代码在,有微则微,无微则宏】
console.log('start')
let promise1 = new Promise(function (resolve,reject) {
console.log('1')
resolve()
console.log('1 end')
}).then(function () {
console.log('2')
})
setTimeout(function(){
console.log('settimeout')
})
console.log('end')
//所以上述代码的执行顺序是:Start->1,->1 end->end->2-> settimeout
20:Promise在哪里使用过
在数据请求的解决回调地狱的时候被使用
以及axios封装时候使用
在service拦截器的时候过
21:js中call()和apply()的区别
call和apply都是调用一个对象的一个方法,用另一个对象替换当前对象。
相同点:两个方法产生的作用是完全一样的。
不同点:方法传递的参数不同,apply第二个参数是数组
22:跨域/同源策略
在前后端分离的模式下,前后端的域名是不一致的,此时就会发生跨域访问问题
跨域问题来源于浏览器的同源策略,是浏览器处于安全方面的考虑,只允许本域名下的接口交互,即只有 同协议,同域名,同端口号相同,则允许相互访问,不同源的客户端脚本,在没有明确授权的情况下,不能读写对方的资源。
也就是说JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。
23:this的指向
This和普通函数连用的时候,谁调用this,this就指向谁
This和构造函数连用的时候,this指向的是new出来的
This和事件连用的时候,this表示触发该事件的事件对象
This和类连用的时候,this表示的是祖父
24:什么是jsonp工作原理,他为什么不是ajax
-
在调用方式上"看起来"很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,
-
ajax和jsonp其实本质上是不同的东西
ajax的核心是通过XmlHttpRequest获取本页内容,
jsonp则是动态添加
25:jsonp和json的区别
1,Jsonp 并不是⼀种数据格式,⽽ json 是⼀种数据格式,它可以被任何的编程语言读取和作为数据格式来传递。
2.jsonp 是⽤来解决跨域获取数据的⼀种解 决⽅案,
3·在开发中。前–>json转为json字符串–>后端解析后生成对应的数据结构
26:深浅拷贝是什么如何实现?
Js中数据分为两种模式
1基本数据类型:值存在堆空间内
2引用数据类型:值会保存在堆空间以及栈空间中,其中栈空间保存的是真实值的地址,该地址指向真实的数据
深拷贝是指:深拷贝的话就会拷贝多层,嵌套的对象也会被拷贝出来,相当于开辟一个新的内存地址用于存放拷贝的对象。
**浅拷贝是指:**如果拷贝基本类型,那么就等于赋值一样,会直接拷贝其本身;但如果拷贝的是引用类型,就只会拷贝一层,如果 原对象发生改变,那么拷贝对象也会发生改变。
深拷贝的实现有三种方式
-
es6中的Object.assign((),obj1)
Let obj1={ Name:”你好” Age:18 } Var obj2=Object.assign({ },obj1) Obj2.name=”李银河” Console.log(obj1. Name) Console.log(obj2. Name)
-
json.parse(json.stringfy())的方式
var obj={ name:"你好", age:18, sex:"女" } var obj2=JSON.parse(JSON.stringify(obj)) obj2.name="李银河" console.log(obj.name) console.log(obj2.name)
27:请输出三种减少页面加载时间的方式
- 图片使用懒加载的方式
- 路由使用懒加载的方式
- 减少http的请求
- 对过大的图片,进行切割,或者使用压缩后的图片
- 对于一些比较小的图片,采用雪碧图的方式
- 压缩js,css文件代码
28:JavaScript 类数组对象的定义?
数组对象和数组类似,但是不能调用数组的方法。拥有 length 属性和若干索引属性的对象就可以被称为类数组对象
例如:arguments 和 DOM 方法的返回结果
类数组转换为数组的方法
-
通过 call 调用数组的 slice 方法来实现转换
Array.prototype.slice.call(arrayLike);
-
通过 call 调用数组的 splice 方法来实现转换
Array.prototype.splice.call(arrayLike, 0);
-
通过 Array.from 方法来实现转换
Array.from(arrayLike);
29:为什么函数的 arguments 参数是类数组
arguments
是一个对象,它的属性是从 0 开始依次递增的数字,还有callee
和length
等属性,但是它们却没有数组常见的方法属性
类数组的遍历
-
将数组的方法应用到类数组上,就可以使用
call
和apply
方法,function foo(){ Array.prototype.forEach.call(arguments, a => console.log(a)) }
-
使用Array.from方法将类数组转化成数组:
function foo(){ const arrArgs = Array.from(arguments) arrArgs.forEach(a => console.log(a)) }
-
使用展开运算符将类数组转化成数组
function foo(){ const arrArgs = [...arguments] arrArgs.forEach(a => console.log(a)) }
方法来实现转换
Array.from(arrayLike);
29:为什么函数的 arguments 参数是类数组
arguments
是一个对象,它的属性是从 0 开始依次递增的数字,还有callee
和length
等属性,但是它们却没有数组常见的方法属性
类数组的遍历
-
将数组的方法应用到类数组上,就可以使用
call
和apply
方法,function foo(){ Array.prototype.forEach.call(arguments, a => console.log(a)) }
-
使用Array.from方法将类数组转化成数组:
function foo(){ const arrArgs = Array.from(arguments) arrArgs.forEach(a => console.log(a)) }
-
使用展开运算符将类数组转化成数组
function foo(){ const arrArgs = [...arguments] arrArgs.forEach(a => console.log(a)) }
第四大部分
转载:https://blog.csdn.net/qq_45903009/article/details/115682710