zoukankan      html  css  js  c++  java
  • ECMAScript5之Object学习笔记(二)

    继续第二部分

    Object.freeze(obj)

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

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

     1     // a person instance
     2     var person = {
     3         name: 'Andrew',
     4         job: 'sales manager'
     5     };
     6 
     7     // before freeze
     8     // existing properties maybe be changed or removed, new properties may be added
     9     person.name = 'Bruce';  
    10     person.age = 30;
    11 
    12     console.log(person.name);  // Bruce
    13     console.log(person.age);   // 30
    14 
    15     // freeze the person
    16     Object.freeze(person);
    17 
    18     // isFrozen
    19     console.log( Object.isFrozen(person) );  // true
    20 
    21     // after freeze
    22     // fail silently, or strict mode throw a TypeError
    23     person.name = 'James'; 
    24     person.age = '35';  
    25     person.gender = 'male'; 
    26 
    27     console.log(person.name);    // Bruce
    28     console.log(person.age);     // 30
    29     console.log(person.gender);  // undefined

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

    我们再来一个例子:

     1     // a person again
     2     var person = {
     3         name: {
     4             firstname: 'Bruce',
     5             lastname: 'Lee'
     6         },
     7         age: 35,
     8         job: 'sales manager',
     9         children: ['lucy', 'linda']
    10     };
    11 
    12     console.log('name:' + person.name.firstname + ' ' + person.name.lastname);  // name:Bruce Lee
    13     console.log('children:' + person.children);       // lucy, linda
    14 
    15     // freeze the person 
    16     Object.freeze(person);
    17 
    18     // has been frozen!
    19     console.log(Object.isFrozen(person));
    20 
    21     // change name
    22     person.name.firstname = 'Andrew';
    23     person.name.lastname = 'Carnegie';
    24 
    25     // add one more child
    26     person.children.push('Tom');
    27 
    28     console.log('name:' + person.name.firstname + ' ' + person.name.lastname);  // name:Andrew Carnegie
    29     console.log('children:' + person.children);   // lucy, linda, Tom

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

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

     1     function deepFreeze(o) {
     2         var prop, propkey;
     3 
     4         Object.freeze(o);
     5 
     6         for(propkey in o) {
     7             prop = o[propkey];
     8 
     9             if( !o.hasOwnProperty(propkey) || !(typeof prop === 'object') || Object.isFrozen(prop) ) {
    10                 continue;
    11             } 
    12             // Recursively call deepFreeze
    13             deepFreeze(prop);
    14         }
    15     };
    16 
    17     // if we use deepFreeze to replace with Object.freeze in the previous example, 
    18     // then nothing will happen, even person's properties(aka. name, age, children ) are changed

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


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

    Object.seal(obj)

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

     1     // a person again
     2     var person = {
     3         name: 'Andrew',
     4         age: 25,
     5         children: ['Tom'],
     6         edu: {
     7             major: 'computer science',
     8             university: 'Yale'
     9         }
    10     };
    11 
    12     // before seal
    13     // new properties may be added, exisiting properties may be changed or removed
    14     person.name = 'Bruce';
    15     person.gender = 'male';
    16     delete person.age;
    17 
    18     // looking up the structure 
    19     console.dir(person);
    20 
    21     // seal the person
    22     Object.seal(person);
    23 
    24     // has been sealed
    25     console.log( Object.isSealed(person) ); // true
    26 
    27     // after seal
    28     // existing (writable) properties can be changed
    29     person.name = 'Jackson';
    30     console.log(person.name);  // Jackson
    31 
    32     // or change value through Object.defineProperty
    33     Object.defineProperty(person, 'name', {value: 'Ann'});
    34     console.log(person.name);  // Anna
    35     
    36     // add one more child
    37     person.children.push('lucy');
    38     console.log(person.children);  // tom, lucy
    39 
    40     // internal object is still extensible, unless you seal it too (eg. Object.seal(person.edu) )
    41     person.edu.degree = 'master';
    42     console.log(person.edu.degree);  // master
    43 
    44     // silently fail or in strict mode throw TypeError
    45     // when add or delete property
    46     person.job = 'Front End Developer'; 
    47     delete person.name; 
    48     // TypeError when add property through Object.defineProperty
    49     Object.defineProperty(person, 'job', {value: 'teacher'}); // TypeError

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

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

  • 相关阅读:
    atitit.ntfs ext 文件系统新特性对比
    Atitit.图片木马的原理与防范 attilax 总结
    Atitit.图片木马的原理与防范 attilax 总结
    Atitit.jdk java8的语法特性详解 attilax 总结
    Atitit.jdk java8的语法特性详解 attilax 总结
    Atitit.远程接口 监控与木马   常用的api 标准化v2 q216
    Atitit.远程接口 监控与木马   常用的api 标准化v2 q216
    Atitit..jdk java 各版本新特性 1.0 1.1 1.2 1.3 1.4 1.5(5.0) 1.6(6.0) 7.0 8.0 9.0 attilax 大总结
    Atitit..jdk java 各版本新特性 1.0 1.1 1.2 1.3 1.4 1.5(5.0) 1.6(6.0) 7.0 8.0 9.0 attilax 大总结
    Atitit.跨平台预定义函数 魔术方法 魔术函数 钩子函数 api兼容性草案 v2 q216  java c# php js.docx
  • 原文地址:https://www.cnblogs.com/AndyWithPassion/p/es5_object_2.html
Copyright © 2011-2022 走看看