記錄一道阿里前端暑期實習筆試題

要求:
1. 私有變量無法被直接讀寫,只能通過 `getter/setter` 進行讀寫。
2. 不能使用任何三方工具
 

const People = (function() {
  // 此處編寫你的代碼
  })();

// 測試用例
const p1 = new People('Lily');
const p2 = new People('Lucy');
const p1 = new People('Lily');
const p2 = new People('Lucy');
console.log(p1.name === undefined);
console.log(p1.getName() === 'Lily');
console.log(p2.name === undefined);
console.log(p2.getName() === 'Lucy');
p1.setName('Tom')
console.log(p1.getName()==='Tom');

題目本身不長,也很好理解,js並沒有對變量進行權限的控制,任何人都可以修改class內部變量,如果要封裝一個class,並且可以set、get,要如何操作呢?

說到封裝,那麼就自然而然想到了閉包,看下面一段代碼:

const People = (function() {
        // 此處編寫你的代碼
        let _name = '';
        let Person = function (name) {
            _name = name;
        };
        Person.prototype.getName = function () {
            return _name;
        };
        Person.prototype.setName = function (newName) {
            _name = newName;
        }
        return Person;
    })();
    const p1 = new People('Lily');
    const p2 = new People('Lucy');
    console.log(p1.name === undefined);//true
    console.log(p1.getName() === 'Lily');//false
    console.log(p2.name === undefined);//true
    console.log(p2.getName() === 'Lucy');//true

    p1.setName('Tom');
    console.log(p1.getName()==='Tom');//true

此處,p1.getName()===‘Lily’爲false,輸出查看後發現p1的name變爲Lucy了,查看代碼後,發現p1、p2共享了一個閉包內的變量_name。

修改爲:

const People = (function () {
        // 此處編寫你的代碼
        let Person = function (name) {
            let _name = name;
            this.getName = function () {
                return _name;
            };
            this.setName = function (newName) {
                _name = newName;
            }
        };
        return Person;
    })();

就輸出5個true了。

 

我又有了一個新的疑問:new出來的,怎麼就是個對象了?

查看紅寶書,書中說new操作有4個步驟:

  1. 創建一個新對象
  2. 將構造函數的作用域賦給新對象
  3. 執行構造函數中的代碼
  4. 返回新對象

嘗試修改代碼模擬上面的過程:

    let People = function (name) {
        let people_name = name;
        let obj = {};
        // obj.__proto__ = People.prototype;
        obj.getName = function () {
            return people_name;
        };
        obj.setName = function (newName) {
            people_name = newName;
        }
        return obj;
    };

    const p1 = new People('Lily');
    
    p1 instanceof People;//false

此時p1具有getName()、setName()的方法,但並不是People的實例(廢話,原型鏈中沒有People.prototype怎麼能是People的實例呢?)

將上面代碼註釋部分取消註釋,輸出

p1 instanceof People;//true

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章