我的最新博客地址:我的最新博客
前言
JavaScript和面向类的语言不同,在ES6出现之前,它其实并没有类来作为对象的抽象模式,所以在描述对象中不免会遇到一个特别的词语,没错就是原型prototype,今天我们讨论的主角也是它,今天我们就来讨论JavaScript原型中的冰山一角。
三道面试题
让我们先来看三道面试题,慢慢的打开你的视野:
先列出三道题目都会用到的对象objProto:
const objProto = {}
// 题目一
objProto.a = 23
const obj = Object.create(objProto)
obj.a = 24
console.log(obj.a)
console.log(obj.hasOwnProperty('a'))
// 题目二
// 设置objProto对象的a属性为只读属性
Object.defineProperty(objProto, 'a', {
enumerable: true,
configurable: true,
value: 23,
writeable: false
})
const obj = Object.create(objProto)
obj.a = 24
console.log(obj.a)
console.log(obj.hasOwnProperty('a'))
// 题目三
Object.defineProperty(objProto, 'a', {
enumerable: true,
configurable: true,
get() {
return 23
},
set() {
console.log('对象objProto的a属性被设置了!')
}
})
const obj = Object.create(objProto)
obj.a = 24
console.log(obj.a)
console.log(obj.hasOwnProperty('a'))
那么你知道上述三道题的答案吗?
让我们来一一进行分析吧:
题目一
对于第一道题,这是我们大多数人都知道并且了解的场景,答案也很明显,没错就是控制台会打印24和true,那么我们再来看看题目一中的对象obj长啥样,如下图:
通过上图我们不难看出,对象a被加在了obj对象的自身属性上了,其原型上的属性a还是原来的23,有没有人会以为改变的是原型上的a属性的值呢?我想还是会有人这样认为的吧。那么为什么a属性被加在obj自身上而不是改变其原型上的a属性呢,obj对象自身原本是不存在a的啊。原因我们待会儿再来解释,我们不妨先来看后面两道题目。
题目二
对于题目二,你的答案又是什么呢?
好吧,先让我来告诉你答案吧,控制台会打印出23和false,哈哈,是不是出乎你的意料呢?那我们再来看看obj对象长啥样吧,如下图:
what fuck?obj对象里面空空如也,为什么,我明明对obj对象的a属性进行赋值操作了啊 obj.a = 24
,既然都进行赋值操作了,那为什么obj对象还空空如也呢,先保留着你的疑问,让我们先来看第三道题目。
题目三
题目三的答案你想到了吗?好了,不卖关子了,直接说了,题目三的控制台会打印23和false,同上我们先来看看obj对象长啥样,如下图:
what fuck?obj.hasOwnProperty(‘a’)不是false吗?为什么控制台打印obj对象,还能看到其自身属性也有a属性?what fuck?这到底是怎么一回事呢?
总结
我们先来总结一下:
对于对象自身不含有的属性而其原型对象含有的属性,当我们设置此属性时的几种情况:
- 如果原型对象objProto的此属性并没有被标记为只读属性,那么会直接在obj对象自身属性上创建该属性为一个新属性,这就是屏蔽属性。
- 如果原型对象objProto的此属性被标记为只读属性,那么无法修改原型的此属性值也无法在对象obj自身上创建该属性,也就是此情况下不会发生屏蔽属性。如果是严格模式下,
obj.a = 24
这行代码会报错,否则赋值语句obj.a = 24
会被忽略,总之不会发生屏蔽。 - 如果原型对象objProto的此属性,并且有setter,那就一定会调用这个setter。根据 obj.hasOwnProperty(‘a’) 的值为false,我们可以得知该属性并不会被添加到obj自身上(可是我们在控制台打印obj又会看到obj自身属性中含有a,对于三,笔者我也没想明白咋回事,明明hasOwnProperty为false,但是又看到了其自身属性确实有a属性的存在,语言bug?)
第一种情况是我们日常开发中遇到的大多数情况,二和三很少遇到,尤其是三,着实让人摸不着头脑,也难怪有很多大神说JavaScript是一门像屎一样的语言,无可厚非,毕竟JavaScript是在短短十天内就被创造出来的,就像我们日常开发一样,时间短速度快那代码自然bug就多呗。虽然JavaScript在某些方面很垃圾,但是其足够的灵活性也让人爱不释手。
好了,今天就聊到这里,有谁知道三是怎么回事的,欢迎给笔者留言。