闭包-访问基本数据类型和引用类型

我们常用闭包的方法来从函数外部访问函数内部的变量

访问一个基本变量类型

保护基本数据的变量,使其不能直接被访问(读,写)

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
}


在这里插入图片描述

个人浅见,入门不久,若果有错误,欢迎指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值