js中Object.defineProperty()方法的不详解


Posted in Javascript onJuly 09, 2018

菜菜: “老大,那个, Object.defineProperty 是什么鬼?”

假设我们有个对象 user ; 我们要给它增加一个属性 name , 我们会这么做

var user = {};
user.name="狂奔的蜗牛";
console.log(user);//{name: "狂奔的蜗牛"}

如果想要增加一个sayHi方法叻?

user.sayHi=function () { console.log("Hi !") };
console.log(user);//{name: "狂奔的蜗牛", sayHi: ƒn}

Object.defineProperty 就是做这个的

那么Object.defineProperty 怎么用?

Object.defineProperty 需要三个参数(object , propName , descriptor)

1 object 对象 => 给谁加
2 propName 属性名 => 要加的属性的名字 【类型:String】
3 descriptor 属性描述 => 加的这个属性有什么样的特性【类型:Object】

那么descriptor这个是个对象 ,他有那些属性呢 ? 别着急我们一个一个说;

既然可以给一个对象增加属性,那么我们用它来做一下给 user添加 name属性,代码是这样的

var user = {};
 Object.defineProperty(user,"name",{
  value:"狂奔的蜗牛"
 })
 console.log(user);//{name: "狂奔的蜗牛"}

说明 是的还是那个经典的value属性,他就是设置属性值的。

等等,属性值只能为字符串吗?我们的 number function Object boolean 等呢?

var user = {};
 Object.defineProperty(user,"name",{
  value:"狂奔的蜗牛"
 })
 Object.defineProperty(user,"isSlow",{
  value:true
 })
 Object.defineProperty(user,"sayHi",{
  value:function () { console.log("Hi !") }
 })
 Object.defineProperty(user,"age",{
  value:12
 })
 Object.defineProperty(user,"birth",{
  value:{
   date:"2018-06-29",
   hour:"15:30"
  }
 })
 console.log(user);

js中Object.defineProperty()方法的不详解

说明 事实证明任何类型的数据都是可以的哦~

问题又来了,如果 user对象已经有了name属性,我们可以通过Object.defineProperty改变这个值吗?

我们来试试

var user = {};
 Object.defineProperty(user,"name",{
  value:"狂奔的蜗牛"
 })
 console.log(user);
 user.name="新=>狂奔的蜗牛"
 console.log(user);

咦??为什么我改了没作用勒??

原因:上边说了descriptor有很多属性,除了value属性还有个 writable【顾名思义属性是否可以被重新赋值】接受数据类型为 boolean(默认为false) true => 支持被重新赋值 false=>只读

哦哦,原来如果我没设置writable值的时候就默认只读啊,所以才改不掉

那我们看看,设置为true,是不是就可以改掉了。

var user = {};
 Object.defineProperty(user,"name",{
  value:"狂奔的蜗牛",
  writable:true
 })
 console.log(user);
 user.name="新=>狂奔的蜗牛"
 console.log(user);

js中Object.defineProperty()方法的不详解

这个descriptor还有其他的属性吗?enumerable【顾名思义属性是否可以被枚举】接受数据类型为 boolean(默认为false) true => 支持被枚举 false=>不支持

额。。。枚举??什....什么意思?

假设我们想知道这个 user对象有哪些属性我们一般会这么做

var user ={
 name:"狂奔的蜗牛",
 age:25
} ;

//es6
var keys=Object.keys(user)
console.log(keys);// ['name','age']
//es5
var keys=[];
for(key in user){
 keys.push(key);
} 
console.log(keys);// ['name','age']

如果我们使用 Object.的方式定义属性会发生什么呢?我们来看下输出

var user ={
 name:"狂奔的蜗牛",
 age:25
} ;
//定义一个性别 可以被枚举
Object.defineProperty(user,"gender",{
 value:"男",
 enumerable:true
})

//定义一个出生日期 不可以被枚举
Object.defineProperty(user,"birth",{
 value:"1956-05-03",
 enumerable:false
})

//es6
var keys=Object.keys(user)
console.log(keys);
// ["name", "age", "gender"]

console.log(user);
// {name: "狂奔的蜗牛", age: 25, gender: "男", birth: "1956-05-03"}
console.log(user.birth);
// 1956-05-03

说明 很明显,我们定义为 enumerable=falsebirth属性并没有被遍历出来,遍历 => 其实就是枚举(个人理解啦,不喜勿喷哦~)

总结 enumerable 属性取值为 布尔类型 true | false 默认值为 false,为真属性可以被枚举;反之则不能。此设置不影响属性的调用和 查看对象的值。

configurable 是接下来我们要讲的一个属性,这个属性有两个作用:

1 属性是否可以被删除
2 属性的特性在第一次设置之后可否被重新定义特性

var user ={
 name:"狂奔的蜗牛",
 age:25
} ;
//定义一个性别 不可以被删除和重新定义特性
Object.defineProperty(user,"gender",{
 value:"男",
 enumerable:true,
 configurable:false
})

//删除一下
delete user.gender;
console.log(user);//{name: "狂奔的蜗牛", age: 25, gender: "男"}

//重新定义特性
Object.defineProperty(user,"gender",{
 value:"男",
 enumerable:true,
 configurable:true
})
// Uncaught TypeError: Cannot redefine property: gender
//会报错,如下图

js中Object.defineProperty()方法的不详解

设置为 true

var user ={
 name:"狂奔的蜗牛",
 age:25
} ;
//定义一个性别 可以被删除和重新定义特性
Object.defineProperty(user,"gender",{
 value:"男",
 enumerable:true,
 configurable:true
})

//删除前
console.log(user);
// {name: "狂奔的蜗牛", age: 25, gender: "男"}

//删除一下
delete user.gender;
console.log(user);
// {name: "狂奔的蜗牛", age: 25}

//重新定义特性
Object.defineProperty(user,"gender",{
 value:"男",
 enumerable:true,
 configurable:false
})

//删除前
console.log(user);
// {name: "狂奔的蜗牛", age: 25, gender: "男"}
//删除一下 删除失败
delete user.gender;
console.log(user);
// {name: "狂奔的蜗牛", age: 25, gender: "男"}

总结 configurable设置为 true 则该属性可以被删除和重新定义特性;反之属性是不可以被删除和重新定义特性的,默认值为false(Ps.除了可以给新定义的属性设置特性,也可以给已有的属性设置特性哈

最后我们来说说,最重要的两个属性 setget(即存取器描述:定义属性如何被存取),这两个属性是做什么用的呢?我们通过代码来看看

var user ={
 name:"狂奔的蜗牛"
} ;
var count = 12;
//定义一个age 获取值时返回定义好的变量count
Object.defineProperty(user,"age",{
 get:function(){
  return count;
 }
})
console.log(user.age);//12

//如果我每次获取的时候返回count+1呢
var user ={
 name:"狂奔的蜗牛"
} ;
var count = 12;
//定义一个age 获取值时返回定义好的变量count
Object.defineProperty(user,"age",{
 get:function(){
  return count+1;
 }
})
console.log(user.age);//13

接下来我不用解释了吧,你想在获取该属性的时候对值做什么随你咯~

来来来,我们看看 set,不多说上代码

var user ={
 name:"狂奔的蜗牛"
} ;
var count = 12;
//定义一个age 获取值时返回定义好的变量count
Object.defineProperty(user,"age",{
 get:function(){
  return count;
 },
 set:function(newVal){
  count=newVal;
 }
})
console.log(user.age);//12
user.age=145;
console.log(user.age);//145
console.log(count);//145

//等等,如果我想设置的时候是 自动加1呢?我设置145 实际上设置是146

var user ={
 name:"狂奔的蜗牛"
} ;
var count = 12;
//定义一个age 获取值时返回定义好的变量count
Object.defineProperty(user,"age",{
 get:function(){
  return count;
 },
 set:function(newVal){
  count=newVal+1;
 }
})
console.log(user.age);//12
user.age=145;
console.log(user.age);//146
console.log(count);//146

说明 注意:当使用了getter或setter方法,不允许使用writable和value这两个属性(如果使用,会直接报错滴)

get 是获取值的时候的方法,类型为 function ,获取值的时候会被调用,不设置时为 undefined

set 是设置值的时候的方法,类型为 function ,设置值的时候会被调用,undefined

get或set不是必须成对出现,任写其一就可以

var user ={
 name:"狂奔的蜗牛"
} ;
var count = 12;
//定义一个age 获取值时返回定义好的变量count
Object.defineProperty(user,"age",{
 get:function(){
  console.log("这个人来获取值了!!");
  return count;
 },
 set:function(newVal){
  console.log("这个人来设置值了!!");
  count=newVal+1;
 }
})
console.log(user.age);//12
user.age=145;
console.log(user.age);//146

js中Object.defineProperty()方法的不详解

【完结】

Object.defineProperty方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象

  • value: 设置属性的值
  • writable: 值是否可以重写。true | false
  • enumerable: 目标属性是否可以被枚举。true | false
  • configurable: 目标属性是否可以被删除或是否可以再次修改特性 true | false
  • set: 目标属性设置值的方法
  • get:目标属性获取值的方法

下一篇,我们来看看怎么用它做一个简单的双向绑定

文章传送门 => 用Object.defineProperty手写一个简单的双向绑定

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery 输入框数字限制插件
Nov 10 Javascript
Javascript 闭包引起的IE内存泄露分析
May 23 Javascript
纯css+js写的一个简单的tab标签页带样式
Jan 28 Javascript
JS中数组Array的用法示例介绍
Feb 20 Javascript
jquery调取json数据实现省市级联的方法
Jan 29 Javascript
原生javascript实现的一个简单动画效果
Mar 30 Javascript
jquery实现图片切换代码
Oct 13 Javascript
JavaScript中校验银行卡号的实现代码
Dec 19 Javascript
无法获取隐藏元素宽度和高度的解决方案
Mar 07 Javascript
JS数组操作之增删改查的简单实现
Aug 21 Javascript
vuex实现的简单购物车功能示例
Feb 13 Javascript
JavaScript canvas实现雪花随机动态飘落
Feb 08 Javascript
微信小程序实现团购或秒杀批量倒计时
Nov 01 #Javascript
微信小程序实现倒计时补零功能
Jul 09 #Javascript
Angular6中使用Swiper的方法示例
Jul 09 #Javascript
微信小程序实现自定义picker选择器弹窗内容
May 26 #Javascript
微信小程序实现漂亮的弹窗效果
May 26 #Javascript
Angular通过指令动态添加组件问题
Jul 09 #Javascript
js实现左右两侧浮动广告
Jul 09 #Javascript
You might like
BBS(php & mysql)完整版(四)
2006/10/09 PHP
PHP实现过滤掉非汉字字符只保留中文字符
2015/06/04 PHP
php遍历替换目录下文件指定内容的方法
2016/11/10 PHP
JavaScript 组件之旅(一)分析和设计
2009/10/28 Javascript
jquery创建表格(自动增加表格)代码分享
2013/12/25 Javascript
JS实现的一个简单的Autocomplete自动完成例子
2014/04/16 Javascript
浅谈JavaScript中定义变量时有无var声明的区别
2014/08/18 Javascript
node.js中的http.request.end方法使用说明
2014/12/10 Javascript
JS实现自动固定顶部的悬浮菜单栏效果
2015/09/16 Javascript
jquery验证邮箱格式并显示提交按钮
2015/11/07 Javascript
JavaScript高级教程5.6之基本包装类型(详细)
2015/11/23 Javascript
jQuery代码实现对话框右上角菜单带关闭×
2016/05/03 Javascript
浅谈js中子页面父页面方法 变量相互调用
2016/08/04 Javascript
微信小程序wx.getImageInfo()如何获取图片信息
2018/01/26 Javascript
详解如何在项目中使用jest测试react native组件
2018/02/09 Javascript
element-ui表格列金额显示两位小数的方法
2018/08/24 Javascript
angularjs http与后台交互的实现示例
2018/12/21 Javascript
Node 代理访问的实现
2019/09/19 Javascript
[04:17]DOTA2完美盛典,rOtk、BurNIng携手巴图演唱《倔强》
2017/11/28 DOTA
Python编程实现使用线性回归预测数据
2017/12/07 Python
python调用摄像头显示图像的实例
2018/08/03 Python
学习python的前途 python挣钱
2019/02/27 Python
python 调试冷知识(小结)
2019/11/11 Python
Python3之乱码\xe6\x97\xa0\xe6\xb3\x95处理方式
2020/05/11 Python
python 实现音频叠加的示例
2020/10/29 Python
python中not、and和or的优先级与详细用法介绍
2020/11/03 Python
介绍一些UNIX常用简单命令
2014/11/11 面试题
竟聘演讲稿范文
2013/12/31 职场文书
奶茶店创业计划书范文
2014/01/17 职场文书
2014年公司庆元旦活动方案
2014/03/05 职场文书
青春无悔演讲稿
2014/05/08 职场文书
2014年学习委员工作总结
2014/11/14 职场文书
花木兰观后感
2015/06/10 职场文书
AI:如何训练机器学习的模型
2021/04/16 Python
PHP实现考试倒计时功能代码
2021/04/16 PHP
MySQL数据库之内置函数和自定义函数 function
2022/06/16 MySQL