深拷贝与浅拷贝
// let a = 10
// let b = a
// b = 20
// console.log(a,b)
// 引用数据类型
// let arr = [1, 2, 3]
// let newArr = arr
// newArr.push(666)
// console.log(arr, newArr)
// let obj = {
// a: 123,
// b: '小明'
// }
// let newObj = obj
// newObj.a = 456
// console.log(newObj, obj)
// 解构赋值?一维数组,一维对象是深拷贝,多维数组,多维对象浅拷贝
// => 深拷贝,浅拷贝 => 假
// let arr = [1, 2, 3]
// let newArr = [...arr]
// newArr.push(666)
// console.log(arr, newArr)
// let arr2 = [[1, 2], [3, 4], [5, 6]]
// let newArr2 = [...arr2]
// newArr2[1].push(666)
// console.log(newArr2, arr2)
// let objA = {
// name: '小明',
// age: 18,
// arr: [1, 2]
// }
// // 深拷贝 function,正则...
// let newObjA = JSON.parse(JSON.stringify(objA))
// newObjA.arr.push(666)
// newObjA.name = '小红'
// console.log(objA, newObjA)
let objA = {
name: '小明',
age: 18,
arr: [1, 2],
aa: function(){
console.log('aa')
}
}
// 标准的深拷贝
function deepClone(source){ // source => 数组 [], 对象 {}
const targetObj = source.constructor === Array ? [] : {}
for(let keys in source){
if(source.hasOwnProperty(keys)){
if(source[keys] && typeof source[keys] === "object"){
targetObj[keys] = source[keys].constructor === Array ? [] : {}
targetObj[keys] = deepClone(source[keys])
}else{
targetObj[keys] = source[keys]
}
}
}
return targetObj
}
let newObjA = deepClone(objA)
newObjA.name = '小红'
newObjA.arr.push(888)
newObjA.aa()
console.log(objA, newObjA)
原型与原型链
// 原型 prototype => 函数特有
// 原型链 _proto_ => [[prototype]]
// let obj = {}
// console.log(obj)
// let arr = []
// obj.prototype.a = 666
// let fn = function fn(){
// }
// console.dir(fn)
// fn.prototype.name = '小明'
// fn.prototype.fn2 = function(){
// console.log("111")
// }
function Person(){
}
Person.prototype.name = '小明'
Person.prototype.age = 18
Person.prototype.getAge = function(){
console.log(this.age)
}
// 实例
let person1 = new Person()
person1.age = 28
person1.demo = 'demo'
console.log(person1)
// person1.getAge()
// person1.abcd()
// 从当前实例属性去查找,如果找了就返回,否则顺着原型链一层一层往上面找
// 直到找到null为止,如果找到null都没有找到,报错
// 找自身的私有属性
let item;
for(item in person1){
if(person1.hasOwnProperty(item)){
console.log(item)
}
}
防抖节流
// 防抖 =>固定的时间内, 事件只允许发生一次
let telInput = document.querySelector('input')
telInput.addEventListener('input', antiShake(demo, 2000))
// 防抖封装
function antiShake(fn, wait){
let timeOut = null;
return args => {
if(timeOut) clearTimeout(timeOut)
timeOut = setTimeout(fn, wait);
}
}
function demo(){
console.log('发起请求')
}
// 节流 => 一定时间内的多个事情合为一个
// 应用场景 => 1. 提交表单 2. 高频监听事件
let box = document.querySelector(".box")
box.addEventListener("touchmove", throttle(demo, 2000))
function throttle(event, time){
let timer = null
return function() {
if(!timer) {
timer = setTimeout(() => {
event();
timer = null;
}, time);
}
}
}
this 指向
//1. console.log(this) Window
// function abcd(){
// console.log(this) // 2. Window
// }
// window.abcd()
// 3.
// let userName = '李四'
// let o = {
// userName: '王武',
// fn1: function(){
// console.log(this.userName)
// }
// }
// o.fn1()
// 谁调用,指向谁 (上一级)
// var j = {
// a: 10,
// b: {
// a: 12,
// fn:function(){
// console.log(this.a)
// }
// }
// }
// j.b.fn()
var id = 66;
function fn5(){
// 1. 箭头函数没有作用域 => 没有this
setTimeout(() => {
console.log(this.id)
}, 500)
}
// fn5({id: 21})
fn5.call({id: 21})
// call, apply, bind
// call, apply 传参的不同 改变 + 执行
// bind() 只改变this的指向,不会执行
new关键字
function Person(){
this.name = '朱小明';
this.fn = function(){
console.log(`名字是:${this.name}`)
}
}
let person1 = new Person()
console.log(person1.name)
person1.fn()
// 1. 创建一个空的对象
let obj = new Object()
// 2. 链接到原型
obj.__proto__ = Person.prototype;
// 3. 绑定this,执行一次构造函数
let result = Person.call(obj)
// 4. 确保返回的是一个对象
if(typeof(result) === "object"){
person1 = result
}else {
person1 = obj
}
// 普通函数 => 默认返回值 undefined
// 构造函数 => 默认返回,新创建的对象
// function a(){
// }
深度剖析js闭包
// 1. 闭包是什么?—— 方法里返回一个方法
// function a(){
// let a1 = 1;
// return function(){
// return a1
// }
// }
// 2. 闭包存在的意义?
// 2.1 延长变量的生命周期
// 2.2 创建私有环境
let a = '小明'
function fn1(){
let b = 1
// console.log(a)
}
// console.log(b)
fn1()
// AO
// 作用域链
// let name = "小明"
// function fn2(){
// // let name = "小白"
// function fn3(){
// // let name = "小红"
// console.log(name)
// }
// fn3()
// }
// fn2()
// 沟通内外部方法桥梁
function outer() {
let a1 = 111;
let a2 = 222;
return function inner(){
return a1;
}
}
function fn5() {
let getInnerData = outer();
console.dir(getInnerData)
}
fn5();
// 闭包会常驻内存 => 慎用闭包
// 闭包 => 私有作用域
// Vue data()为什么是一个函数?
// data(){
// return {
// }
// }
// 不用闭包,obj = {}
let makeCounter = function () {
let num = 0;
function changeBy(val){
num += val
}
// 给你什么,你才能拿
return {
add: function() {
changeBy(1)
},
reduce: function() {
changeBy(-1)
},
value: function() {
return num
}
}
}
let counter1 = makeCounter()
let counter2 = makeCounter()
counter1.add()
counter1.add() // 2
// counter2 // 0
counter2.add() //
console.log(counter2.value()) // 1
console.log(counter1.value()) // 2
// 都有独立的词法作用域
// 面向对象编程 ———— 数据的隐藏和封装
网友评论