文章目录
1. js基础
数据类型
基本数据类型:numder,undefined,string,Boolean,symbol,
应用类型: array,function,object,null,
值类型
他都是在栈中存储的 因为他占地空间小。
常见的值类型:undefined,numder,string,Boolean,symbol
引用类型
他会在堆中申请一个地址,把数据放在堆中,
topeof运算符
它可以判断所有的类型,还能判断函数,能识别引用类型函数(不能细分)
深拷贝
function deepClone(obj={}){
// 判断是否为引用类型
if(typeof obj!=='object'||obj==null){
return obj
}
// 初始化返回结果
let res
if(obj instanceof Array){
res=[]
}else{
res={}
}
for(let key in obj){
// 保证 key 不是原型的属性
if(obj.hasOwnProperty(key)){
// 递归调用
res[key]=deepClone(obj[key])
}
}
// 返回结果
return res
}
类型判断 instanceof
它可以判断应用类型
要判断的类型instanceof类型// true 或 false
2.原型与原型链
原型的关系
每个class都有显示原型 prototype
每个实例都有隐式原型__proto__
实例的__proto__指向对应class的prototype
1. prototype
每一个函数都有一个prototype属性,被称为显示原型
2.proto
- 每一个实例对象都会有__proto__属性,被称为隐式原型
- 每一个实例对象的隐式原型__proto__属性指向自身构造函数的显式原型prototype
3. constructor
每个prototype原型都有一个constructor属性,指向它关联的构造函数。
4. 原型链
获取对象属性时,如果对象本身没有这个属性,那就会去他的原型__proto__上去找,如果还查不到,就去找原型的原型,一直找到最顶层(Object.prototype)为止。Object.prototype对象也有__proto__属性值为null。
原型的执行规则
当获取属性方法时,首先在滋生属性和方法中寻找,如果找不到就会去_proto_中寻找。
原型链
手写简易jQuery
class jQuery{
constructor(selector){
const result = document.querySelectorAll(selector)
const length = result.length
for(let i = 0; i < length; i++){
this.length = length
this.selector = selector
}
}
get(index){
return this[index]
}
each(fn){
for(let i = 0; i < this.length; i++){
const elem = this[i]
fn(elem)
}
}
on(type,fn){
return this.each(elem => {
elem.addEventListener(type,fn,false)
})
}
}
// 插件
jQuery.prototype.dialog = function(info){
alert(info)
}
class myJQuery wxtends jQuery{
constructor(selector){
super(selector)
}
// 扩展自己的方法
say(){}
}
const $p = new jQuery('p')
$p.get(1)
$p.each(elem=>{console.log(elem.nodeName)})
$p.on('click',()=>{alert('ckicked')})
3.作用域与闭包
作用域
它代表某个变量的使用范围,出范围会报错。
上图,每一个红框代表一个作用域
作用域分为:
全局作用域
函数作用域:只能在当前函数中使用
块级作用域(ES6 新增):
// 块级作用域 let const
if(true){
let x=100
}
console.log(x) //会报错
自由变量
1.一个变量在当前作用域没有定义,但被使用了。
2.向上级作用域,一层一层查找,直到找到为止。
3.如果到全局作用域都没有找到,就会报错。
可以参照上图作用域
闭包
它是作用域应用的特殊情况,有两种:
1.函数作为返回值被返回
function create() {
let a = 100
return function () {
console.log(a)
}
}
let fn = create()
let a = 200
fn() //100
2.函数作为参数被传递
function print(fn) {
let a = 200
fn()
}
let a = 100
function fn() {
console.log(a)
}
print(fn) //100
自由变量的查找,是在函数定义的地方,向上级作用域查找,不是在执行的地方。
this 指向
使用场景:
1.作为普通函数
2.使用 call apply bind
3.作为对象方法被调用
4.在class方法中调用
5.箭头函数
this取什么值是函数执行时确认的,不是在函数调用时确认的。
function fn1() {
console.log(this)
}
fn1() // x:100
fn1.call({ x: 100})
const fn2 = fn1.bind({ x: 200})
fn2() // x:200
箭头函数的this指向不会改变,始终指向它的上一级
异步
JS是单线程语言,只能同时做一件事
同步
console.log(100)
alert(200)
console.log(300)
// 100 200 300
异步
console.log(100)
setTimeout(()=>{
console.log(200)
},1000)
console.log(300)
// 100 300 200
两者的区别:
异步不会阻塞代码执行
同步会阻塞代码执行
使用场景:
网络请求(如:ajax请求)、定时任务(如:setTimeout)。
setTimeout:一次性定时器,只执行一次。
setInterval:间接性定时器,可执行多次。
数组方法
push()
可以接受一个或者多个参数,将参数追加到数组的尾部,返回添加后的数组的长度,原数组会发生改变。
pop()
从数组尾部删除一个元素,返回这个被删除的元素,原数组发生改变
unshift()
可以接受一个或者多个参数,将参数放到数组的头部,返回添加后的数组的长度,原数组会发生改变。
shift()
从数组头部删除一个元素,返回这个被删除的元素,原数组发生改变。
slice()
截取类 如果不传参数,会返回原数组;如果一个参数,从该参数表示的索引开始截取,直至数组结束,返回这个截取数组,原数组不变;两个参数,从第一个参数对应的索引开始截取,到第二个参数对应的索引结束,但不包括第二个参数对应的索引上值,原数组不改变;最多接受两个参数
splice()
截取类 没有参数,返回空数组,原数组不变;一个参数,从该参数表示的索引位开始截取,直至数组结束,返回截取的 数组,原数组改变;两个参数,第一个参数表示开始截取的索引位,第二个参数表示截取的长度,返回截取的 数组,原数组改变;三个或者更多参数,第三个及以后的参数表示要从截取位插入的值。
reverse()
不接受参数,数组翻转。
sort() 排序
arr.sort(function(a,b){
return a-b; //从小到大排序
return b-a; //从大到小排序
});
join()
参数来拼接;分隔符。
concat()
将参数放入原数组后返回,原数组本身不变,如果参数是数组,将值提出来。
isArray()
判断是否是数组
toString()
数组转字符串
indexOf()
从前往后遍历,返回item在数组中的索引位,如果没有返回-1;通常用来判断数组中有没有某个元素。可以接收两个参数,第一个参数是要查找的项,第二个参数是查找起点位置的索引。