JS核心之ES5应用基础(一)

62 阅读3分钟

简洁

ES5是ECMAScript标准的第五个升级版本,对JS规则做出一些补充和修改。

严格模式

使用方法

这段程序的顶部,写 “use strict”;

使用效果

未声明的变量禁止赋值

普通模式:会自动创建全局变量,易造成全局污染,内存泄漏。
严格模式:无法赋值,报错为变量未定义,避免了全局污染,内存泄漏。

静默失败升级为报错

普通模式:执行未成功不报错,不便于调试。
严格模式:执行不成功即报错,利于问题定位。

this默认指向undefined

普通模式:普通函数调用与匿名函数自调用中,没有调用者的情况下默认this指向window。
严格模式:没有调用者的情况下this默认指向undefined。

arguments.callee使用被限

普通模式:在函数内部获得函数本身,可在递归中使用,避免了紧耦合。
严格模式:禁用arguments.callee。

保护对象

保护属性

数据属性

普通模式:属性为普通变量,随意更改。
严格模式:
将数据属性变为缩微对象,保存了一个属性值与三个开关,属性值为数据属性的值,三个开关控制着属性是否可以修改等。
例:属性名为eid,属性值为100,的属性内部。

eid:{
	value:100,
	writable:true/false, //属性值是否可修改
	enumerable:true/flase, //属性是否可被for-in遍历
	configurable:true/false //是否可删除该属性,是否可修改前两个开关,修改为false不可逆
}

三个开关无法直接用.来访问,ES5为其设置了专门的访问方法。

Object.defineProperty(
	对象名,
	"属性名",
	{
		开关: true/false
	}
)

Object.defineProperty()一次只能修改对象中的一个属性。
修改多个属性需要使用 Object.defineProperties()。

Object.defineProperties(
	对象名,
	{
		属性名:{
			开关:true/false
		},
		属性名:{
			开关:true/false
		},
	}
)

通过缩微开关来保护属性,是固定的,然而有时我们需要使用自定义规则来保护属性,如控制属性被修改的内容,根据条件判断是否允许本次修改等,这时候就用到访问器属性

访问器属性

访问器属性本身不保存数据,专门提供对其它数据属性的保护。
首先定义一个普通的对象。

function(){
	var eric = {
		ename:"埃里克",
		eage:26
}

假设要对上例中的eage数据属性进行保护,需要定义一个新的属性_eage替代eage,在原来的eage中放置两个函数get和set,用来被调用时自动调用,当被赋值时调用set,经过验证后将值赋给_eage,当直接调用时调用get,返回_eage的值,虽然表面上是对eage进行操作,实际上存储数据的值变为了_eage

Object.defineProperties(eric,{
	//值给_eage
	_eage:{
		value:eric.eage,
		writable:true,
		enumerable:false,
		configurable:false
	},
	//定义访问器属性顶替_eage
	eage:{
		get:function(){
			return this._eage;
		},
		set:function(value){
				if(value>=18&&value<=65){
					this._eage = value;
				else{
					throw Error("年龄超范围!")
				}
			},
			enumerable:true,
			configurable:false
		}
})
eric.eage = 27;//修改成功
console.log(eric.eage);//调用
eric.eage = 10;//报错,年龄超范围

保护结构

防扩展

阻止对obj对象添加扩展属性。

Object.preventExtensions(obj);

该函数改变了obj对象内部隐藏bool属性值,该属性用来判断是否可扩展。

密封

防扩展,防删除。

Object.seal(obj)

此函数在禁止添加新属性的同时,也禁止删除现有属性,即在放扩展的基础上将configurable开关属性置为false。

冻结

在上一步的基础上禁止修改属性的值。即在密封的基础上将writable改为false。