JS ES5(ECMAScript5)的学习笔记

本文介绍了JavaScript的严格模式,包括其启用方式和新引入的约束,如禁止未声明变量赋值、错误处理的改变等。同时,讲解了如何通过Object.defineProperty和访问器属性保护对象,防止随意修改。
摘要由CSDN通过智能技术生成
1.严格模式

1.什么是严格模式:在原有的js运行机制上增加了一系列约束,来约束原有js中包含的缺陷和功能。
2.启用严格模式:在但钱作用域的顶部添加:‘use strict’;
3.严格模式新增的约束:
①禁止给未声明的变量赋值;
原js中,给未声明的变量赋值,不会报错,会在全局中声明一个变量并强行赋值,会造成全局污染和内存泄漏;
在严格模式下,会报错,不会在全局中声明变量。
②静默失败升级为失败,会报错;
静默失败:执行不成功,也不会报错。容易产生歧义,干扰调试。
③普通函数调用和匿名函数自调中的this不再指向window,而是指向undefined。
避免了因为this引起的全局污染和内存泄漏
④禁用了arguments.callee
arguments.callee:专门在函数内部获得当前正在执行的函数自己,虽然arguments.callee可以实现递归算法的松耦合,但是,严格模式下不推荐使用递归算法,因为递归的运行效率极低(重复计算量极大)
原js中几乎所有递归调用都应该使用arguments.callee

// 斐波那契数列
// 递归思路,原js使用arguments.callee获得当前正在执行的函数自己
function f(n) {
	if(n < 3) {
		return 1;
	} else {
		return arguments.callee(n - 1) + arguments.callee(n + 1);
	}
}
// 循环思路
function f(n) {
	if (n < 3) {
		return 1;
	} else {
		var f1 = 1,  f2 = 1, fn;
		for (var i = 3; i <= n;  i++ ) {
			fn = f1 + f2;
			f1 = f2;
			f2 = fn;
		}
		return fn;
	}
}

2.保护对象

1.什么是保护对象:阻止程序对一个对象执行不合常理的修改。
原js,没有保护对象
①保护单个属性:阻止对对象中某个属性执行不合常理的修改;
②保护对象结构:阻止乱添加删除属性。

ES5对对象的属性也进行了分类

(1)命名属性:所有可用 ‘.’ 访问的属性–需要保护,又进一步分为:①数据属性:实际存储属性值的属性;②访问器属性:自己不实际存储属性值,而是对另一个弱小的数据属性提供保护。
(2)内部属性:存在于对象中,但是不允许使用 ‘.’ 访问的属性–不需要保护。

如何保护一般的数据属性
  1. ES5中的每个数据属性都存在四个属性值,分别是:①value(存储属性值);②writable(属性值是否可修改:true/false);③enumerable(是否允许for in循环遍历到这个属性,半隐藏属性);④configurable(是否可以删除,同时控制着writable和enumerable属性值是否可以修改);

  2. 怎么修改数据属性的属性值?
    ①单个数据属性修改:

Object.defineProperty(对象名, '属性名',
	{
		writable/enumerable/configurable: true/false,
		... : ...
	 }
);

②同时修改多个数据属性的属性值:

Object.defineProperties(对象,
	 {
		属性名1:{
			writable/enumerable/configurable: true/false
			, ... : ...
		},
		{
			属性名2:{
				writable/enumerable/configurable: true/false
		},
		{... : ...}
	}
);

3.访问器属性
①访问器属性:自己不实际保存属性值,仅提供对另外一个数据属性的保护。
②使用访问器属性:使用访问器的属性跟使用普通属性的方法一样。
(1)获取访问器的属性值:对象名.属性名;
当外界想获取访问器属性的属性值时,js会自动调用访问器属性的get()方法,从实际保存数据的半隐藏的属性中,读取出现在的属性值,return给外部
(2)修改访问器的属性值: 对象名.属性名 = 新值;
当外界想修改访问器属性的属性值时,js会自动调用set()方法,把新值传给set()方法的形参,并在验证后保存或者报错

var student = {
	sid: 101,
	sage: 18,
	grade: 1
}
// 学生的年级(grade)可以修改,且范围只能在1-4
// ①创建一个半隐藏属性保存当前属性
Object.defineProperty(student, "_grade", {
	value: student.grade,
	writable: true,
	enumerable: false, // 半隐藏
	configurable: false
});
// ②设置该属性的get()和set()方法
Object.defineProperty(student, 'grade', {
	// 读取现在的属性值,返回到外部
	get() {
		return this._grade;
	},
	// 接受外部的新值(value),验证通过则保存,不通过则报错
	set(value) {
		if (value >= 1 && value <= 4) {
			this.grade = value;
		} else {
			throw Erro("班级超出范围");
		}
	},
	// 因为访问器属性步存储实际的属性值,所以没有value和writable属性
	enumerble: true,
	configurable: false
});

4.保护对象的结构
禁止对对象添加新属性,删除现有属性;
①防扩展: Object.preventExtensions(对象);禁止对对象添加新属性。
原理:每个对象都有一个内部属性extensible,默认为true,调用Object.preventExtensions(对象)后会自动把extensible设为false,从而禁止添加新属性
②密封:Object.seal(对象);禁止对对象添加新属性和删除现有属性
原理:把对象的内部属性extensble(是否可以添加新属性)和configurable(是否可以删除现有属性)都设为false
③冻结: Object.freeze(对象);禁止对对象添加新属性和删除现有属性,还禁止修改对象的属性值
原理:把对象的内部属性extensble(是否可以添加新属性)和configurable(是否可以删除现有属性)都设为false, 并且把对象的writable(是否可以修改属性的属性值)设为false

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值