记录一道阿里前端暑期实习笔试题

要求:
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

 

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