闭包、私有属性

本文详细解释了JavaScript中闭包的概念及其如何导致内存占用增加。通过示例代码展示了闭包的作用域链机制,并提供了解决方案来避免内存泄漏。同时介绍了如何利用闭包保护私有属性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当内部函数被保存到外部时,将会生成闭包。闭包会导致原油作用域链不释放,造成内存占用。

// 练习题
function test(){
	var arr = [];//定义一个数组,里面放10个function
	for (var i = 0; i < 10; i++) {
		arr[i] = function(){
			document.write(i+" ");
		}
	}
	return arr;//返回到外部
}
// 用myArr接收返回的数组
var myArr = test();//执行test函数 返回arr装了10个function
// 调用十个function
for (var j = 0; j < 10; j++) {
	myArr[j]();//打印的10个都是10
}



// 解析:
test  定义  test.[[scope]]--->0:GO
test  执行  test.[[scope]]--->0:testAO {i:0}
			    1:GO

arr[i] 定义 arr[i].[[scope]]--->0:testAO
test  执行  test.[[scope]]--->0:testAO {i:0}-test的for循环执行完后->{i:10}
			      1:GO
返回arr 在外部执行  此时的i已经为10
arr[i] 执行 arr[i].[[scope]]--->0:arr[i]AO
				1:testAO {i:10}

用立即执行函数解决这个闭包打印相同i的问题

function test(){
	var arr = [];//定义一个数组,里面放10个function
	for (var i = 0; i < 10; i++) {
		(function(j){
			arr[j] = function(){
				document.write(j+" ");
			}
		}(i));
	}
	return arr;//返回到外部
}
// 用myArr接收返回的数组
var myArr = test();//执行test函数 返回arr装了10个function
// 调用十个function
for (var j = 0; j < 10; j++) {
	myArr[j]();//打印的10个都是10
}

// 解析:
test  定义  test.[[scope]]--->0:GO
test  执行  test.[[scope]]--->0:testAO {arr:undefined,i:0}
							  1:GO
执行时  test.[[scope]]--->0:testAO {arr:undefined,i:0}
							  1:GO
		执行立即执行函数--->立即执行函数的[[scope]]--->0:立即执行的AO{j:0}
													   1:testAO {arr[0]:undefined}
		arr[0] 定义 arr[0].[[scope]]--->0:立即执行的AO{j:0}
								 	    1:testAO {arr[0]:function}
		依次循环
		arr[1] 定义 arr[1].[[scope]]--->0:立即执行的AO{j:1}
								 	    1:testAO {arr[0]:function}

test  执行  test.[[scope]]--->0:testAO {i:0}-test的for循环执行完后->{i:10}
							  1:GO
返回arr 在外部执行  此时的i已经为10  但是每个arr[j]里面的j是分别保存的123456789
arr[j] 执行 arr[j].[[scope]]--->0:arr[j]AO
								1:立即执行的AO{j:1}   0-9
								2:testAO {arr[0]:function}


// 通过闭包,建自己的私有属性。
function Person(name){
	// 为了别人能访问属性,却无法看到、修改属性。
	// 用var 在构造函数内部定义属性。
	// 如果用this,别人可以随意修改
	var money = 100;
	this.name = name;
	this.makeMoney = function(){
		money++;
	}
	this.pay = function(){
		money--;
	}
// ---------------------------
	// 当new实例化后。构造函数内部会隐性
	// var this = {
	// 		里面有this上的属性或方法。这里只有两个方法
	// 		makemoney()  pay()
	// }
	// 在最后会隐性return this;
	// 那么money会在Person的AO中保存,并且被传到外部。
	// 于是在外部依然能访问到money。只是无法修改

}
// 当实例化对象时 让他可以通过方法,使money增减。
// 却无法看到我的money,也无法直接修改money
var person = new Person();

 

### JavaScript 中类的私有属性实现与用法 在 JavaScript 中,私有属性是通过在属性名前加上 `#` 哈希符号来定义的。这种语法允许开发者创建只能在类内部访问的属性或方法,从而增强了封装性和安全性。以下是关于私有属性的具体实现与用法的详细说明。 #### 私有属性的基本语法 私有属性的声明需要使用 `#` 符号作为前缀。以下是一个简单的例子,展示了如何定义和使用私有属性: ```javascript class Point { #x; // 私有属性 #y; // 私有属性 constructor(x, y) { this.#x = x; this.#y = y; } equals(point) { return this.#x === point.#x && this.#y === point.#y; } } const p1 = new Point(1, 2); const p2 = new Point(1, 2); console.log(p1.equals(p2)); // true ``` 在上述代码中,`#x` 和 `#y` 是私有属性,无法从类外部直接访问[^3]。 #### 私有属性的特性 1. **不可从外部访问**:私有属性只能在类的内部访问,尝试从外部访问会抛出错误。 ```javascript console.log(p1.#x); // 报错:SyntaxError: Private field '#x' must be declared in an enclosing class ``` 这一行为由 JavaScript 引擎强制执行[^2]。 2. **支持私有方法**:除了私有属性,还可以定义私有方法。私有方法同样以 `#` 开头。 ```javascript class Foo { #method = () => { console.log('This is a private method'); }; callPrivateMethod() { this.#method(); } } const foo = new Foo(); foo.callPrivateMethod(); // 输出: This is a private method ``` 在此示例中,`#method` 是一个私有方法,只能通过类的公共方法调用[^1]。 3. **兼容性问题**:私有属性和方法是 ES2022 的新增特性,因此需要确保目标环境支持该特性。如果不支持,可以通过 Babel 等工具进行转译。 #### 使用闭包实现私有属性(旧方式) 在引入 `#` 私有字段之前,JavaScript 社区通常使用闭包来模拟私有属性的功能。以下是一个示例: ```javascript class Test { constructor() { let name = 'test'; // 私有变量 this.getName = function () { return name; }; this.setName = function (newName) { name = newName; }; } } const test = new Test(); console.log(test.getName()); // 输出: test test.setName('newTest'); console.log(test.getName()); // 输出: newTest console.log(test.name); // undefined ``` 在这种方式中,`name` 是通过闭包实现的私有变量,无法从类外部直接访问[^4]。 ### 总结 现代 JavaScript 提供了简洁且强大的私有属性语法,通过 `#` 符号可以轻松定义私有字段和方法。这种方式不仅提高了代码的可读性,还增强了封装性和安全性。对于不支持最新标准的环境,可以通过闭包模拟私有属性的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值