js實現(xiàn)私有屬性

1.命名實現(xiàn)

第一個方法是使用特定的命名約定來表示屬性應(yīng)該被視為私有。通常以下劃線作為屬性名稱的前綴(例如 _name )。但這并不能阻止變量被訪問或修改,而是依賴于開發(fā)者之間的相互約定,認(rèn)為這個變量應(yīng)該被視私有屬性。

class Person {
     constructor(name, age) {
       this._name = name;
       this._age = age;
     }
     getName() {
       return this._name;
     }
     setName(newName) {
       this._name = newName;
     }

   }
   const test = new Person('張三',24)

2.閉包實現(xiàn)

第二個方法是利用js提供的強大的閉包,閉包背后的想法是將數(shù)據(jù)封裝在調(diào)用時創(chuàng)建的函數(shù)作用域內(nèi),但是從內(nèi)部返回函數(shù)的結(jié)果,從而使這一作用域無法從外部訪問。

const Person = () => {
      let name = '張三';
      let age = 24;
      return {
        getName() {
          return name;
        },
        setName(newName) {
          name = newName;
        }
      }
    }
    const test1 = Person();
    test1.getName() //張三
    test1.setName('李四');
    test1.getName()// 李四

3.Symbol+ 閉包實現(xiàn)
第三個方法是利用es6提供的新特性Symbol與閉包一起使用,(如果你還不熟悉Symbol,請參閱 ECMAScript 6 入門)

 const person2 = (name, age) => {
      const _name = Symbol('name');
      const _age = Symbol('age');
      return class Person {
        constructor() {
          this[_name] = name;
          this[_age] = age;
        }
        getName() {
          return this[_name];
        }
        setName(newName) {
          this[_name] = newName;
        }
      }
    }
    const Test2 = person2('張三', 24);
    const test3 = new Test2();
    console.log('test3', test3);

4.*Proxy + 方法一
第四個方法是利用es6提供的新特性Proxy與方法一一起使用((如果你還不熟悉Proxy,請參閱 ECMAScript 6 入門)),使用Proxy進行攔截+命名式的代碼可以讓這些私有變量在類外部訪問受限。

const person3 = (name, age) => {
      class Person {
        constructor(name, age) {
          this._name = name;
          this._age = age;
        }
        getName() {
          return this._name;
        }
        setName(newName) {
          this._name = newName;
        }
      }
      const handle = {
        get(target, key) {
          if (key[0] === '_') {
            throw new Error('該屬性為私有屬性')
          } else if (key === 'toJSON') {
            const obj = {}
            //防止JSON.stringify 序列化  如果一個被序列化的對象擁有 toJSON 方法,那么該 toJSON 方法就會覆蓋該對象默認(rèn)的序列化行為:不是那個對象被序列化,而是調(diào)用 toJSON 方法后的返回值會被序列化。
            for (const key in target) {
              if (key[0] !== '_') {
                obj[key] = Reflect.get(target, key);
              }
            }
            return obj;
          }
          return Reflect.get(target, key);
        },
        set(target, key, value) {
          if (key[0] === '_') {
            throw new Error('該屬性為私有屬性')
          }
          Reflect.set(target, key, value);
        },
        // 禁止 for in 枚舉
        getOwnPropertyDescriptor(target, key) {
          const desc = Reflect.getOwnPropertyDescriptor(target, key);
          if (key[0] === '_') {
            desc.enumerable = false;
          }
          return desc;
        }
      }
      return new Proxy(new Person(name, age), handle);
    }
    const test4 = person3('張三', 24);
    test4._namr // error
    JSON.stringify(test4); // {};

完整的代碼實例:https://github.com/summer789/studyJS/blob/master/privateProperty.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 原文地址:http://yacare.iteye.com/blog/2010049 很多伙伴在更新VS2010,或...
    zaza81閱讀 154評論 0 0
  • 聲明閉包的格式: var popBlock : (() -> Void)? 聲明一個無參數(shù),無返回值的可選類型閉包
    柳絮風(fēng)微閱讀 275評論 0 0
  • 健康方面: 1.吃: 有三天吃麵包、麵、炒飯等不是那麼健康的食品,配湯是蔬菜湯,算是有點平衡。還有一天吃速食炸物套...
    卓俊良l0073365踐行閱讀 150評論 0 0
  • 高爾基說過:書籍是人類進步的階梯。全人類的事我們可能想不了太多,但是可以讓自己去做一個堅持閱讀的人。 閱讀能帶給我...
    今小汐閱讀 1,422評論 2 3
  • “外向型思維模式”害死你 各位小伙伴們,大家好,我是四妹, 我平時有時間喜歡看愛情保衛(wèi)戰(zhàn)這個欄目,因為在里面可以...
    我是四妹閱讀 786評論 0 0

友情鏈接更多精彩內(nèi)容