js属性类型以及vue的基本原理


参考ECMAScript5

属性有2种,数据属性和访问器属性。

数据属性:
  拥有4个特性:

  Configurable 表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。默认为true,如果将其设置为false,则不能再变回true了,除了writable特性可以设置以外,其余都不可设置

  Enumerable 表示能修改通过for-in循环返回属性。默认为true

  Writable 表示能否修改属性的值。默认为true

  Value 包含这个属性的数据值。默认为underfined


这4个特性是内部值,不能直接访问,只能使用Object.defineProperty()方法进行修改。

eg:
  Object.defineProperty(obj,key,{writable:false,value:'abc});

  如果在使用其创建新属性时不指定特性值,则默认值都是false,如果是修改已定义的则无此限制


访问器属性:
  访问器属性不包含数据值,它们包含一对getter和setter函数,拥有以下4个特性:


  前2个特性是一样的,之后的2个特性为get和set

 

  访问器属性不能直接定义,必须使用Object.defineProperty创建访问器属性。

 

  可以使用Object.defineProperties(obj,json)来创建多个属性


我们知道vue有个很好用的特性,即数据双向绑定,这里我试着编写了一个简单的具有双向绑定特性的构造函数:

  

function CL(obj) {
  this.template = obj.template
  try{
    this.target = obj.el.charAt(0) === '#'?document.getElementById(obj.el.substr(1)):document.getElementsByClassName(obj.el.substr(1))[0]
  }catch (err){
    console.log(err)
  }
  if(typeof obj.data == 'function'){this.data = obj.data} else{
    console.log('data must a function')
  }
  if(this.data){
    let obj = this.data()
    setObject.call(this,obj,this)
  }

  this.target.innerHTML = formatString(this.template,this)

  Object.freeze(this)
}

function formatString(str,data) {
  return str.replace(new RegExp('\{\{(.+)\}\}','g'),(match,$1)=>{
    if (new RegExp('.','g').test($1)) {
      var arr = $1.split('.')
      return data[arr[0]][arr[1]]
    }else {
      return data[$1]
    }
  })
}

function setObject(obj,This) {
  for (let key in obj) {
    Object.defineProperties(this,{
      _data:{
        writable:true,
        value:(typeof obj[key] == 'object')?new setObject(obj[key],This):obj[key]
      },
      [key]:{
        get(){
          return this._data
        },
        set(newVal){
          this._data = newVal
          This.target.innerHTML = formatString(This.template,This)
        }
      }
    })
  }
}

  后续会对这段代码进行解释,写的比较随意,如有错误请指正。

posted @ 2017-10-15 22:55  桃李不言~  阅读(898)  评论(0编辑  收藏  举报