背景
作为一个前端新人,免不了加各种群,和其他小伙伴们一同进修(chui bi),互相帮助(bi can)。头几天一个小伙伴在群里发了道本身去口试的笔试题,我写了一下,一时间没能完成,本日又折腾了一下,虽然大抵完成了,但不晓得是不是文雅,分享本身解法的同时也想请大佬指导一二。
题目
编写一个名字为Person的对象,请求
有一个name属性,外部只能接见不能修正,初始化时赋值。
内部保护一个叫things的局部变量,数组范例,用于存储购置的物品(something)清单。
有一个buy(something)要领,用于购置物品(something)
具有count属性,用于指导一共买了若干物品。
剖析
看到这题的第一回响反映就是用组织函数/class来写。Person对象应当就是一个Person类。
两个属性一个要领,嗯,没什么题目。只要2个点须要斟酌:
一、 这个things局部变量是个啥?是属性吗?
应当不是,既然特地指出了,一定有他的斟酌,那末既然是局部变量,外部也是接见不到的,这个应当用闭包写。
二、 name属性外部只能接见不能修正.
这个用闭包也能处理,然则如许记不能经由过程组织函数/class来完成了,背离了初志,不可(不过我背面照样会给出这类写法)。那末(以我的程度)就只能用
Proxy
或许class
,这2个都能阻拦对象属性的读/写。2种我都试过,采纳Proxy,缘由下面会讲。
代码
class Person {
constructor(name,count=0) {
this.name = name;
this.count = count;
this.init()
}
//初始化函数
init() {
var things = [];
Person.prototype.buy = (something) => { //为了构成闭包,显式将buy要领写到Person的原型上
things.push(something);
this.count = things.length;
}
}
}
//Proxy handler对象,定义行动
var handler = {
set(target,prop,value,receiver) {//阻拦set行动
if(prop == 'name') {
throw Error('不能够哦') //这里自定义你的逻辑,也能够alert等。
}
Reflect.set(target,prop,value,receiver) //不要忘了对其他属性'放行'
}
}
var p1 = new Proxy(new Person('张三'),handler)
console.log(p1.name) //张三
p1.name = '李四' //Error:不能够哦
p1.buy('猫粮');
p1.buy('猫砂');
console.log(p1.count) //2
//假如须要从'内部'修正p1的名字,则须要先对被代办对象举行定义
var _p1 = new Person('张三');
var p1 = new Proxy(_p1,handler)
console.log(p1.name); //张三
_p1.name = '李四';
console.log(p1.name) //李四
以上我对这道题的明白。至于为何不必class的setter,是由于如许写后,在new Person的时刻不能传name进去,由于一传进去就会被阻拦。所以只能先初始化对name赋值,再举行proxy代办对name阻拦。
另一种“野门路”写法
var Person = function(name,count=0) {
var things = [],name = name
result = {
count = count;
};
result.__proto__ = {
buy:function(something) {
things.push(something);
result.count = things.length;
},
getName:function() { // 经由过程getName函数来猎取名字
return name;
}
}
return result;
}
var p2 = Person('王五');
p2.getName() //王五
p2.name = 123;
p2.getName() //王五
p2.buy('妙鲜包');
console.log(p2.count) // 1
两种要领见仁见智,第二种野门路不必Proxy代办,返回的是Object对象,而第一种正规军则返回Person对象,更相符题意。
结语
写到这不晓得人人发现了没。 实在第一种要领也能够不须要proxy代办,再init
函数中定义name = this.name,再在Person原型上写一个getName
函数,如许2种要领的长处就结合到一同了Σ(っ °Д °;)っ
这2小时没有白花,这文章没有白写,又赚到了^ ^。
愿望能给人人带来一点点收成,假如有差别的意见能够留言一同讨论()。
Thanks for reading