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

  • 相关阅读:
    csp-s模拟103
    csp-s模拟102
    csp-s模拟101
    csp-s模拟100
    csp-s模拟99
    csp-s模拟98
    csp-s模拟97
    csp-s模拟96
    csp-s模拟95
    csp-s模拟94
  • 原文地址:https://www.cnblogs.com/AndyWithPassion/p/es5_object_2.html
Copyright © 2011-2022 走看看