对象属性

其实我在一年前就想过一个问题,JS有事件机制,那么变量能不能有事件机制呢?1

Intro

这个问题就在最近得到了回答2,然后我试着运用在了最近写的播放器 bp-player 3 上,效果还可以吧,有时候能达到非常好的使用效果,但是缺点就是不能用太多,可能是我水平太弱没用正确的方式编写吧。

总所周知,JS里除了那几个4以外,其它的都是由对象组成,即使是数字,也会自动返回一个Number对象,字符串亦是如此。也因为JS的对象机制,使得这个语言既有趣又坑爹。


Object(999) instanceof Number //true Object('helloString') instanceof String //true

正是因为这样,你才可以用得到诸如'string'.substr(3)(9).toExponential()之类的写法,也才能用到函数的链式写法。

对象的属性

废话不多说了,对象的属性(property)即 一组无序集合中的项目,这个项目一定要有个名字,而且在这一组集合里不会有重名的项目。JS里的对象允许直接添加属性:


let obj = {}; obj.a = 999; obj.b = 888; obj.c = 222; obj; //Object {a: 999, b: 888, c: 222}

还有一个比较特别的是,查找对象里一个不存在的属性,则会返回 undefined


let obj = {}; console.log(obj.a); //undefined console.log(obj['b']); //undefined

属性行为

对象属性似乎就两种行为,一种是取值(get), 一种是赋值(set)。JS内部通过 gettersetter 来对对象属性进行 取值/赋值 的操作。

对的,我想你可能猜得到了,JS提供了定义属性行为的方式。


let people = { name: 'vec', _age: 19, }; Object.defineProperty(people, 'age', { get(){ return this._age; }, set(value){ if ( value < 0 ){ alert('这个世界上没有小于0岁的人'); }else{ this._age = value; } } }); people.age = 20; console.log(people.age); //20 people.age = -999; //'这个世界上没有小于0岁的人' console.log(people.age); //20

可以使用 Object.defineProperty 方法定义一个对象属性的行为,也可以用 Object.properties 方法定义多个对象属性。


let obj = {}; Object.definePropertise(obj, { propertyA: { get(){ /* do something */ }, set(){ /* do something */ }, }, propertyB: { get(){ /* do something */ }, set(){ /* do something */ }, } });

callback

那么,到底可以做什么用?根据我在 bp 上的实践,其实用处挺大的,而且使用得当非常好,比如一个播放器的列表指针


class List{ getCurrent(){ return this.list[this.cursor]; } reloadSong(){ this.audio.src = this.getCurrent(); this.audio.load(); this.audio.play(); } constructor(list){ this.audio = new Audio; this.list = list; this._cursor = 0; Object.defineProperty(this, 'cursor', { get(){ return this._cursor; }, set(value){ if ( isNaN(value) ){ alert('请使用有效的数字'); } else if ( value >= this.list.length ){ alert('你这个数值设定的太大了'); } else if ( value < 0 ){ alert('小于0也是不行不能不可以的'); }else{ this._cursor = parseInt(value); this.reloadSong(); } } }); this.reloadSong(); } }

只要正确修改了 cursor 属性,就会执行一次reloadSong方法,对于使用者来说,只需要换个 cursor 就可以切换曲目了,个人觉得挺简洁的

但是,东西虽好,可不要多玩。。。我之前在bm.js上的实践就是这样,写的很乱,有点后怕了orz

嗯,似乎没有什么好讲了,我也该去睡觉了,唉,还有好多东西要学,好多东西……


  1. 类似于 typechange、valuechange、change之类的名字吗( ↩︎

  2. 《Javascript高级程序设计》 ↩︎

  3. 包括 bp-core.js、bp-frame、bm.js ↩︎

  4. 比如 undefinednulltruefalse之类的…… ↩︎