动态数据绑定(一)
- <a href="http://ife.baidu.com/course/detail/id/15">题目</a>
- <a href="https://github.com/CaiYiLiang/2017ife-Baidu/blob/master/vue-DynamicDataBinding%2301.js">作业源码</a>
- 考察知识点:
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty">Object.defineProperty(ES5)</a>,
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys(ES5)</a>,
<a href="http://wwsun.github.io/posts/javascript-oo-summary.html">Prototype原型对象</a>,
<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/new">New 操作符</a>
在看完在线学习参考资料后,用了ES5和ES6两种语法完成作业。
并且对ES6的Class类语法糖有更深一层的认识。
用ES5的语法完成的代码如下:
// ES5 Syntax
function Observer(obj){
this.walk(obj)
}
var p = Observer.prototype //函数Observer的原型对象
p.data = {} // 定义一个原型对象的属性data,这个属性被每个实例共享
// 定义原型对象的方法walk,这个方法会在每个实例对象创建时被调用
p.walk = function(obj){
Object.keys(obj).forEach(function(key){
if(typeof obj[key] === "object"){return p.walk(obj[key])}
Object.defineProperty(p.data,key,{
get:function(){ console.log("You are visiting the attribute: "+ key+" - "+obj[key]); return obj[key] },
set:function(newValue) { console.log("You are updating the attribute: "+ key+" - "+ newValue); obj[key] = newValue }
})
})
}
关于Object.defineProperty的实践新知
Object.defineProperty(obj, prop, descriptor)用于直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象。
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个拥有可写或不可写值(value)的属性。存取描述符是由一对 getter-setter 函数功能来描述的属性。
描述符必须是两种形式之一;不能同时是两者。
用ES6的语法完成的代码如下:
// ES6 Syntax
Object.prototype.data = {};
class Observer{
constructor(obj){
this.walk(obj)
}
walk(obj){
Object.keys(obj).forEach(key => {
if(typeof obj[key] === "object"){return Observer.prototype.walk(obj[key])}
Object.defineProperty(data,key,{
get:() => { console.log("You are visiting the attribute: "+ key+" - "+obj[key]); return obj[key] },
set:newValue => { console.log("You are updating the attribute: "+ key+" - "+ newValue); obj[key] = newValue }
})
})
}
}
是否对data对象
的声明方式Object.prototype.data = {};
感到奇怪,为什么不直接在Class类里面声明原型对象属性,但如果真的这样做,浏览器会报错。
原因是ES6 Class类里不支持直接定义原型对象的属性,只支持定义原型对象的方法(参考传送门:<a href="http://stackoverflow.com/questions/22528967/es6-class-variable-alternatives">StackOverflow</a>)。
其中两点比较重要:
The notes in the ES wiki for the proposal in ES6 (maximally minimal classes) note:
There is (intentionally) no direct declarative way to define either prototype data properties (other than methods) class properties, or instance property
Class properties and prototype data properties need be created outside the declaration.
文:ES6中的class没有直接定义原型对象属性(除非是用method实现)和实例对象属性的声明方法。
Maximally minimal classes is still at its very core prototypical inheritance. What you really want to do in your case is share structure and assign members for each instance. This is simply not what classes in ES6 aim for - sharing functionality. So yes, for sharing structure you'd have to stick to the old syntax. Until ES7 at least :) – Benjamin Gruenbaum
文:ES6中的class类是以实现核心典型的原型链继承为目标。而你想实现使每个实例对象获得共享属性/成员。共享功能 -- 这恰恰就不是ES6-class类的目标。因此,如果想要实现属性/成员变量共享结构,应该坚持使用旧的语法。直到ES7 :) – Benjamin Gruenbaum
原创文章
简书:<a href="//www.greatytc.com/u/c0600377679d">HelloCherry</a>
Github: <a href="https://github.com/CaiYiLiang">CaiYiLiang</a>
Girhub / vue-demos:
- <a href="https://github.com/CaiYiLiang/simply-calculator-vuejs" >利用vue.js实现简易计算器</a>
- <a href="https://github.com/CaiYiLiang/vue-demos/tree/master/wikipediaViewer-vuejs">实现简单的单页面应用(vue2.0,vue-router,vue-cliand ajax(jsonp))</a>
- <a href="https://github.com/CaiYiLiang/vue-demos/tree/master/shoppingcart-vuejs" >利用vue.js,vuex,vue-router和 Element UI实现购物车场景</a>
很高兴写的<a href="https://github.com/CaiYiLiang/vue-demos">vue demos</a>被收录到 <a href="https://github.com/vuejs/awesome-vue">awesome-vue</a>中,简直就是一朵小红花😋
如果觉得有一点点帮助,一个❤❤就是鼓励(。⌒∇⌒)