我们常用闭包的方法来从函数外部访问函数内部的变量
访问一个基本变量类型
保护基本数据的变量,使其不能直接被访问(读,写)
function operateBaseVariable(){
let a = 10
function getA() {
return a
}
function setA(any){
a = any
}
return {
getA,
setA,
}
}
let opertaeBase = operateBaseVariable()//这是一个对象,对象里面包含两个函数
//获取a的值
opertaeBase.getA()
//设置a的值
opertaeBase.setA('a 被重新设置了')
这是一个对 敏感数据 a 的封装,封装的原则之一,尽可能少的暴露内部实现的方法,虽然这里将数据 a 保护起来了,但是我们却将操作它的方法暴露了,所以可以改进:
function operateBaseVariable(){
let a = 10
function getA() {
return a
}
function setA(any){
a = any
}
return {
getBaseA: getA,
setBaseA: setA,
}
}
let opertaeBase = operateBaseVariable()//这是一个对象,对象里面包含两个函数
//获取a的值
opertaeBase.getBaseA()
//设置a的值
opertaeBase.setBaseA('a 被重新设置了')
这里我们如果要操作访问数据 a 只能通过getBaseA() 和 setBaseA()两个方法,那么其他开发者并不知道 读写a 内部是如何完成的,只知道可以通过这两个方法来完成想要的操作
访问一个引用数据类型(数组)
如何保护一个数组呢?直接上代码
function operateComplexVariable(){
let arr = [1,2,3]
function getArr() {
let newArr = [...arr] //深拷贝
return newArr
}
function pushArr(any){
arr.push(any)
}
return {
getComplexArr: getArr,
pushComplexArr: pushArr,
}
}
let opertaeComplex = operateComplexVariable()//这是一个对象,对象里面包含两个函数
//获取arr的值
opertaeBase.getComplexArr()
//设置a的值
opertaeBase.pushComplexArr('arr push 的数据')
访问一个引用数据类型(对象)
function obj() {
let mySymbol = Symbol() /* es6 出现的新的基本数据类型,我只是想要使用一下 */
let obj = {
name: '张三',
age: 18,
sex: '男',
[mySymbol]: 'symbol数据'
}
function getObj(){
let newobj = {}
Object.assign(newobj,obj)
return newobj
}
function setObj(setObj){//setObj应该是个对象
//Object.assign(obj,setObj)
//对象只有一级属性时,用这个方法深拷贝没有问题
//在对象的二级属性为引用类型时,这个方法就是浅拷贝二级属性了了
//更改
return JSON.parse(JSON.stringify(obj ))
}
return {
getObject: getObj,
setObject: setObj,
}
}
let objOperate = obj()
objOperate.getObject()
objOperate.setObject({add: '新增数据'})
console.log(objOperate.getObject())
这个和基本类型数据不同的是,若在获取的函数中直接公开 arr(这是一个地址)的话,根本没有起到保护它的作用,原因就是引用类型在内存中的存储
基本数据存储是直接存在栈当中,这里误操作不会影响保护起来的a 的值
引用数据类型是存在堆当中, 若直接返回受保护的arr 误操作会改变arr的值, 而如果是这样操作,深拷贝一下,就算在外部有误操作也不会影响受保护的 arr 因为被改变的是 arr 的替身 newArr
Object.assign
复制原理,内部实现可能是这样的
//由上面的错误的思考
Object.assign = function(newObj,oldObj) {
for(let key in oldObj) {
newObj[key]=oldObj[key]
}
return newObj
}
个人浅见,入门不久,若果有错误,欢迎指正。