ECMAScript5之Object学习笔记(二)

2023-04-24,,

继续第二部分

Object.freeze(obj)

看字面意思就是“把一个对象冻结”。

下面我们来看个简单的例子以作说明:

     // a person instance
var person = {
name: 'Andrew',
job: 'sales manager'
}; // before freeze
// existing properties maybe be changed or removed, new properties may be added
person.name = 'Bruce';
person.age = 30; console.log(person.name); // Bruce
console.log(person.age); // // freeze the person
Object.freeze(person); // isFrozen
console.log( Object.isFrozen(person) ); // true // after freeze
// fail silently, or strict mode throw a TypeError
person.name = 'James';
person.age = '35';
person.gender = 'male'; console.log(person.name); // Bruce
console.log(person.age); //
console.log(person.gender); // undefined

上面例子的特点是,person对象的属性像name,job,age的值都是“字面值”,并非对象,如果存在一个属性,其值是一个对象呢?

我们再来一个例子:

     // a person again
var person = {
name: {
firstname: 'Bruce',
lastname: 'Lee'
},
age: 35,
job: 'sales manager',
children: ['lucy', 'linda']
}; console.log('name:' + person.name.firstname + ' ' + person.name.lastname); // name:Bruce Lee
console.log('children:' + person.children); // lucy, linda // freeze the person
Object.freeze(person); // has been frozen!
console.log(Object.isFrozen(person)); // change name
person.name.firstname = 'Andrew';
person.name.lastname = 'Carnegie'; // add one more child
person.children.push('Tom'); console.log('name:' + person.name.firstname + ' ' + person.name.lastname); // name:Andrew Carnegie
console.log('children:' + person.children); // lucy, linda, Tom

通过上面的2个例子,我们很容易得出结论。那么我们如何做到“深层”freeze呢。

就要用到一个递归函数,来让里面的每个对象都被freeze:

     function deepFreeze(o) {
var prop, propkey; Object.freeze(o); for(propkey in o) {
prop = o[propkey]; if( !o.hasOwnProperty(propkey) || !(typeof prop === 'object') || Object.isFrozen(prop) ) {
continue;
}
// Recursively call deepFreeze
deepFreeze(prop);
}
}; // if we use deepFreeze to replace with Object.freeze in the previous example,
// then nothing will happen, even person's properties(aka. name, age, children ) are changed

利用的deepFreeze方法,我们就可以把person对象的属性全部“冻结”。


搞清楚Object.freeze的用途后,我们继续来了解下Object.seal

Object.seal(obj)

seal从字面意思上理解有“密封”的意思,我依旧通过例子来说明:

     // a person again
var person = {
name: 'Andrew',
age: 25,
children: ['Tom'],
edu: {
major: 'computer science',
university: 'Yale'
}
}; // before seal
// new properties may be added, exisiting properties may be changed or removed
person.name = 'Bruce';
person.gender = 'male';
delete person.age; // looking up the structure
console.dir(person); // seal the person
Object.seal(person); // has been sealed
console.log( Object.isSealed(person) ); // true // after seal
// existing (writable) properties can be changed
person.name = 'Jackson';
console.log(person.name); // Jackson // or change value through Object.defineProperty
Object.defineProperty(person, 'name', {value: 'Ann'});
console.log(person.name); // Anna // add one more child
person.children.push('lucy');
console.log(person.children); // tom, lucy // internal object is still extensible, unless you seal it too (eg. Object.seal(person.edu) )
person.edu.degree = 'master';
console.log(person.edu.degree); // master // silently fail or in strict mode throw TypeError
// when add or delete property
person.job = 'Front End Developer';
delete person.name;
// TypeError when add property through Object.defineProperty
Object.defineProperty(person, 'job', {value: 'teacher'}); // TypeError

通过上面的例子,我们可以看到,seal一个对象后,使得它不可扩展,但是其属性值(该属性writable为true)是 可以改变的。还有一点就是若其属性是一个对象,姑且叫内部对象吧,那么这个内部对象还是可以进行扩展的,除非写一个递归的deepSeal方法, 这个可以参考上面的deepFreeze

第二部分就到这里,感兴趣的同学可以前往MDN查看,Object.freeze,Object.seal。

ECMAScript5之Object学习笔记(二)的相关教程结束。

《ECMAScript5之Object学习笔记(二).doc》

下载本文的Word格式文档,以方便收藏与打印。