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
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的常用转态码:
变量提升是:无论是在函数的何种位置声明变量,该变量都不会报错函数的声明会被提前到函数的顶部,在全局变量中也是一样的
为什么会出现变量提升:
主要得益于js脚本语言在浏览器中的运行机制,js的运行会分为两部分
(1):代码的解析过程:js会在代码进行解析的时候,现将即将使用到的所有的变量进行提前赋值,赋值为undefined,同时也会将即将执行的函数进行提前声明,这些都会在全局上下文中执行,在函数提前声明之前,也会创建一个函数的上下文,函数的上下文会包括(this,参数,argument)
(2):代码的执行过程:按照执行顺序进行依次执行
Undefined:常用来表示一个定义了但是没有赋值的变量,Undefined不是一个保留关键字
Null:常用来表示一个还没有存在的对象
判断:
两者在不严格等于的情况下是相等的
但是在严格等于的情况下是不相等的
采用typeof检测的时候,undefined返回undefined,null返回的是object
转换为数字的时候,undefined会返回NaN,null会返回0
Undefined的值出现有四种情况:
数据定义了但是没有赋值
数组中空出来的值
对象没有相应的方法和属性
函数没有返回值的时候
===
、==
的区别?双等号进行相等判断时,如果两边的类型不一致,则会进行强制类型转化后再进行比较。
三等号进行相等判断时,如果两边的类型不一致时,不会做强制类型准换,直接返回 false
使用 Object.is 来进行相等判断时,一般情况下和三等号的判断相同,它处理了一些特殊的情况,比如 -0 和 +0 不再相等,两个 NaN 认定为是相等的。
闭包就是能够读取其他函数内部变量的函数。闭包函数的使用必须使用var关键字声明变量
闭包的缺点:容易造成内存泄漏
闭包的优点:可以内部变量访问外部变量,可以永久的保存某些变量
闭包的造成是:浏览器中自带的垃圾回收机制
垃圾回收机制:在 Javascript 中,如果⼀个对象不再被引⽤,那么这个对象就会被垃圾回收机制回收。如果两个对象互相引⽤,⽽不再 被第 3 者所引⽤,那么这两个互相引⽤的对象也会被回收
垃圾回收机制的方法:1。标记清除,2。引用计数
事件委托就是利用事件冒泡,只制定一个事件处理程序,就可以管理某一类型的所有事件。
事件委托的好处:
将某一个事件加在父元素身上,提高程序的执行效率
要是动态创建的元素,会给新创建好的元素提前绑定触发事件
事件委托的方法:
父元素.事件=function(evt){
//获取事件的真正操作源
Var e = evt || event;
//真正的操作元素
var target = e.srcElement || e.target;
}
//确定事件源采用target.tagName
特性 | 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():删除所有的键值对
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声明的变量不会:
let,const
模板字符串``,使用内容+$(变量)
箭头函数
对象解构
解构对象:let {name,age,sex}=[name:”li”,age:5,sex:”女”]
解构数组:let {x,y,a }=[1,3,5]
逆运算符[…obj]
for in(不能遍历对象)和for of
ES6中的类
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}), 过滤数组,返回一个满足要求的数组
箭头函数是ES6中的提出来的,它没有prototype,也没有自己的this指向,更不可以使用arguments参数,所以不能New一个箭头函数。
命名规则上:构造函数一般大写,普通函数一般采用驼峰命名法
调用的时候:构造:new fun();普通:fun()
This的指向区别:构造:new出来的 ;普通:谁调用指向谁
箭头函数书写更加简洁高级,多变
//无参
()=>{
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
对象:用于取出参数对象中的所有可遍历属性
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];
**原型:**绝大部分的函数都有⼀个 prototype 属性,这个属性是原型对象⽤来创建新对象实例,而所有被创建的对象都会共享原型对象,因此这些对象便可以访问原型对象的属性。
hasOwnProperty() ⽅法存在于Obejct原型对象中,它便可以被任何对象当做⾃⼰的⽅法使⽤. object.hasOwnProperty( propertyName )可以判断该对象是否有该原型
**原型链:**是每个对象都有 proto 属性,此属性指向该对象的构造函数的原型。对象可以通过 proto 与上游的构造函数的原型对象连接起来,⽽上游的原型对象也有⼀个 proto ,这样就形成了原型链。
**继承:**利用原型中的成员可以被和其相关的对象共享这一特性,可以实现继承,这种实现继承的方式,就叫做原型继承.
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
在数据请求的解决回调地狱的时候被使用
以及axios封装时候使用
在service拦截器的时候过
call和apply都是调用一个对象的一个方法,用另一个对象替换当前对象。
相同点:两个方法产生的作用是完全一样的。
不同点:方法传递的参数不同,apply第二个参数是数组
在前后端分离的模式下,前后端的域名是不一致的,此时就会发生跨域访问问题
跨域问题来源于浏览器的同源策略,是浏览器处于安全方面的考虑,只允许本域名下的接口交互,即只有 同协议,同域名,同端口号相同,则允许相互访问,不同源的客户端脚本,在没有明确授权的情况下,不能读写对方的资源。
也就是说JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。
This和普通函数连用的时候,谁调用this,this就指向谁
This和构造函数连用的时候,this指向的是new出来的
This和事件连用的时候,this表示触发该事件的事件对象
This和类连用的时候,this表示的是祖父
在调用方式上"看起来"很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,
ajax和jsonp其实本质上是不同的东西
ajax的核心是通过XmlHttpRequest获取本页内容,
jsonp则是动态添加
1,Jsonp 并不是⼀种数据格式,⽽ json 是⼀种数据格式,它可以被任何的编程语言读取和作为数据格式来传递。
2.jsonp 是⽤来解决跨域获取数据的⼀种解 决⽅案,
3·在开发中。前–>json转为json字符串–>后端解析后生成对应的数据结构
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)
数组对象和数组类似,但是不能调用数组的方法。拥有 length 属性和若干索引属性的对象就可以被称为类数组对象
例如:arguments 和 DOM 方法的返回结果
类数组转换为数组的方法
通过 call 调用数组的 slice 方法来实现转换
Array.prototype.slice.call(arrayLike);
通过 call 调用数组的 splice 方法来实现转换
Array.prototype.splice.call(arrayLike, 0);
通过 Array.from 方法来实现转换
Array.from(arrayLike);
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);
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))
}
第四大部分