Open xiaochengzi6 opened 2 years ago
所有的属性都具备了属性描述符【数据描述符】,它有四个特性
{ value: , configurable: , writable: , enumerable: , }
value特性:保存属性的值,configurable特性:属性是否可配置,属性是否能删除;enumerable特性:属性可枚举,除了value其余三个的值为布尔类型,在创建一个对象的属性的时候使用默认值
var obj = {}; obj.a = 3 //默认值 { value: 3 , configurable: true, writable: true, enumerable: true, }
使用Object.defineProperty(...)来添加一个属性或设置一个属性。
Object.defineProperty(...)
var obj = {}; Object.defineProperty(obj,'a',{ value: 3 , configurable: true, writable: true, enumerable: true, }) obj.a //3
如何判断什么时候添加还是设置一个属性呢看一个例子:
let object = { a: 'ss' } let uu = Object.create(object); uu.a //return 'ss' Object.defineProperty(uu, 'a', { configurable: true, value: 2, })
在这里是创建还是修改一个对象的属性呢
//hasOwnProperty()判断一个属性是否在它自身上 console.log(uu.hasOwnProperty('a')) //true
可以看到是明显的创建属性
uu.__proto__.a //return 'ss' uu.a // return 2 //属性的屏蔽的作用
在设置input的数据劫持中想通过这样的方式来绑定数据
//html: <input type="number" class="input" value="3"> let input = document.querySelector('.input'); input.addEventListener('click', function () { Object.defineProperty(input, 'value', { get() { console.log('get') }, set(){ console.log('set') } }) }, false)
在浏览器中并不能返回想要的答案
input.value // return 3 在HTML中input的value=3 input.hasOwnProperty('value') //false
value属性并不是存在于自身,这个value是html特性映射过来的dom属性,input继承的是x的(object)value的属性,在Object.defineProperty操作中就会出现问题,这里就相当于创建了一个value的属性。
value
html
dom
Object.defineProperty
这里还有一个问题怎样判断属性来源于那个对象
对象属性的设置的过程
var obj = {}; obj.a = 'NO' obj.a //return 'NO' let objs = { foo: '123', }; let per = Object.creat(objs); per.foo //return '123' per.foo = 'jj'; per.foo === 'jj'; per.__proto__.foo === '123'; 属性发生了屏蔽 //这里会有几个过程 1. 如果在[[Prototype]]链上层存在名为foo的普通数据访问属性(参见第3章)并且没有被标记为只读(writable:false),那就会直接在myObject中添加一个名为foo的新属性,它是屏蔽属性。 2. 如果在[[Prototype]]链上层存在foo,但是它被标记为只读(writable:false),那么无法修改已有属性或者在myObject上创建屏蔽属性。如果运行在严格模式下,代码会抛出一个错误。否则,这条赋值语句会被忽略。总之,不会发生屏蔽。 3. 如果在[[Prototype]]链上层存在foo并且它是一个setter(参见第3章),那就一定会调用这个setter。foo不会被添加到(或者说屏蔽于)myObject,也不会重新定义foo这个setter。 如果你希望在第二种和第三种情况下也屏蔽foo,那就不能使用=操作符来赋值,而是使用Object.defineProperty(..)(参见第3章)来向myObject添加foo。
当给一个对象的属性定义 get set 或者两者都有时这个属性就会被定义为访问描述符,
let text = document.querySelector('.text'); input.addEventListener('click', function () { Object.defineProperty(text, 'value', { get() { console.log('get') }, set(){ console.log('set') } }) }, false)
更关注于 get set这样的属性和configurable和enumerable特性,忽略value 和wriable特性
1. in 操作符检查属性是否在对象或者他的原型中 2. object.hasOwnProperty(..) 判断属性是否在其对象中 3. object.propertyIsEnumerable(..)检查给定的属性名是否存在对象中而不是原型链中并且满足 enumerable = true
<body> <div id="app"> <input type="number" id="txt"> <p id="show-txt"></p> </div> </body> <script> var obj = {} let txt = document.querySelector('#txt'); Object.defineProperty(obj, 'txt', { get: function () { return obj }, set: function (newValue) { document.getElementById('txt').value = newValue document.getElementById('show-txt').innerHTML = newValue } }) txt.addEventListener('click', function (e) { obj.txt = e.target.value }) </script>
页面input点击后把他的value赋值给一个对象的属性,通过劫持这个对象的属性开始判断页面是否发生变化,input变化后页面也随之变化
input
属性描述符
所有的属性都具备了属性描述符【数据描述符】,它有四个特性
value特性:保存属性的值,configurable特性:属性是否可配置,属性是否能删除;enumerable特性:属性可枚举,除了value其余三个的值为布尔类型,在创建一个对象的属性的时候使用默认值
使用
Object.defineProperty(...)
来添加一个属性或设置一个属性。如何判断什么时候添加还是设置一个属性呢看一个例子:
在这里是创建还是修改一个对象的属性呢
可以看到是明显的创建属性
在设置input的数据劫持中想通过这样的方式来绑定数据
在浏览器中并不能返回想要的答案
value
属性并不是存在于自身,这个value是html
特性映射过来的dom
属性,input继承的是x的(object)value的属性,在Object.defineProperty
操作中就会出现问题,这里就相当于创建了一个value的属性。这里还有一个问题怎样判断属性来源于那个对象
对象属性的设置的过程
访问器描述符
当给一个对象的属性定义 get set 或者两者都有时这个属性就会被定义为访问描述符,
更关注于 get set这样的属性和configurable和enumerable特性,忽略value 和wriable特性
判断存在性
实现一个简单的数据绑定功能
原理: