Object的defineProperty、define​Properties、get​OwnProperty​Descriptor、get​OwnProperty​Descriptors方法

一、Object.defineProperty() : 在一个对象上定义新属性或者修改现有属性,并返回这个对象。
语法:

Object.defineProperty(obj, prop, descriptor)
参数:
obj: 要在其上定义或修改属性的对象
props: 要定义或修改属性的名称
descriptor: 将被定义或修改的属性描述符

属性描述符
有两种主要形式:数据描述符存取描述符
1、数据描述符和存取描述符均具有以下可选键值

  • configurable 当且仅当该属性的值为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false
  • enumerable当且仅当该属性的enumerable为true时,该属性可枚举。默认为 false。

2、数据描述符同时具有以下可选键值

  • value该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。
  • writable当且仅当该属性的writable为true时,value才能被赋值运算符(=、+=、-=、*=、/=、%=、…)改变。默认为 false。

3、存取描述符同时具有以下可选键值

  • get 一个给属性提供 getter 的方法,默认值undefined,访问该属性时,该方法会被执行。
  • set 一个给属性提供 setter 的方法,默认值undefined,属性值被修改时触发执行该方法,该方法接受唯一参数即该属性新的参数值。

描述符可同时具有的键值如下图(摘自MDN)所示:

MDN属性描述图
如果一个描述符不具有value,writable,get 和 set 任意一个关键字,那么它将被认为是一个数据描述符。如果一个描述符同时有(value或writable)和(get或set)关键字,将会产生一个异常。

例子

var obj = new Object();

Object.defineProperty(obj, 'name', {
    configurable: false,
    writable: true,
    enumerable: true,
    value: '李明'
})

console.log(obj.name)  //李明

二、Object.defineProperties() :在一个对象上定义一个或多个新属性或者修改现有属性,并返回这个对象。
语法:

Object.defineProperties(obj, props)
obj: 要在其上定义或修改属性的对象
props: 要定义或修改属性的名称

例子

var obj = {};
Object.defineProperties(obj, {
  'property1': {
    value: true,
    writable: true
  },
  'property2': {
    value: 'Hello',
    writable: false
  }
  // etc. etc.
});

三、Object.getOwnPropertyDescriptor() : 方法返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)
语法:

Object.getOwnPropertyDescriptor(obj, prop)

obj:需要查找的目标对象
prop:目标对象内属性名称

例子

var o, d;

o = { get foo() { return 17; } };
d = Object.getOwnPropertyDescriptor(o, "foo");
// d {
//   configurable: true,
//   enumerable: true,
//   get: /*the getter function*/,
//   set: undefined
// }

注:在es5中如果第一个参数不是对象会报错。但在ES2015中会把第一个不是对象的参数转为对象处理

Object.getOwnPropertyDescriptor('foo', 0);
// 类型错误: "foo" 不是一个对象  // ES5 code

Object.getOwnPropertyDescriptor('foo', 0);
// Object returned by ES2015 code: {
//   configurable: false,
//   enumerable: true,
//   value: "f",
//   writable: false
// }

四、Object.getOwnPropertyDescriptors() : 用来获取一个对象的所有自身属性的描述符。如果没有任何自身属性,则返回空对象。
语法:

Object.getOwnPropertyDescriptors(obj)

例子

var person = {
name: '张三',
age: 18
}
var desc = Object.getOwnPropertyDescriptors(person);
console.log(desc) 

结果如下:
{
age:{
	configurable: true
	enumerable: true
	value: 18
	writable: true
},
name:{
	configurable: true
	enumerable: true
	value: '张三'
	writable: true
}
}

拓展示例:
例一:

var a =  1;
var d = Object.getOwnPropertyDescriptor(window, 'a');

console.log(d)
// {
//     configurable: false,
//     value: 1,
//     writable: true,
//     enumerable: true
// }

例二:

a=1;//a相当于window的一个属性, window.a
var d = Object.getOwnPropertyDescriptor(window, 'a');
console.log(d)

// {
//     configurable: true,   // 此时configurable属性值为true
//     value: 1,
//     writable: true,
//     enumerable: true
// }

例三;

var b = {
    name: 'bbb'
}
var d = Object.getOwnPropertyDescriptor(b, 'name');
console.log(d)

// {
//     configurable: true
//     writable: true,
//     enumerable: true
//     value: 'bbb'
// }

通过以上三个例子比较可得:使用 var,let定义的任何变量,其configurable属性值都为false,使用字面量定义的对象,该对象内部的属性的数据描述符属性都为true。

get和set实现简易的数据双向绑定
html代码:

<body>
    <p>
        input1=><input type="text" id="input1">
    </p>
    <p>
        input2=>
        <input type="text" id="input2">
    </p>
    <div>
        我每次比input1的值加1=>
        <span id="span"></span>
    </div>
</body>

js代码:

var oInput1 = document.getElementById('input1');
var oInput2 = document.getElementById('input2');
var oSpan = document.getElementById('span');
var obj = {};
Object.defineProperties(obj, {
    val1: {
        configurable: true,
        get: function() {
            oInput1.value = 0;
            oInput2.value = 0;
            oSpan.innerHTML = 0;
            return 0
        },
        set: function(newValue) {
            oInput2.value = newValue;
            oSpan.innerHTML = Number(newValue) ? Number(newValue) : 0
        }
    },
    val2: {
        configurable: true,
        get: function() {
            oInput1.value = 0;
            oInput2.value = 0;
            oSpan.innerHTML = 0;
            return 0
        },
        set: function(newValue) {
            oInput1.value = newValue;
            oSpan.innerHTML = Number(newValue)+1;
        }
    }
})
oInput1.value = obj.val1;
oInput1.addEventListener('keyup', function() {
    obj.val1 = oInput1.value;
}, false)
oInput2.addEventListener('keyup', function() {
    obj.val2 = oInput2.value;
}, false)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值