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 相关文章推荐
关于Blog顶部的滚动导航条代码
Sep 25 Javascript
深入认识JavaScript中的函数
Jan 22 Javascript
jquery验证表单中的单选与多选实例
Aug 18 Javascript
jQuery中html()方法用法实例
Dec 25 Javascript
javascript伸缩型菜单实现代码
Nov 16 Javascript
JSON字符串转换JSONObject和JSONArray的方法
Jun 03 Javascript
微信小程序 五星评分(包括半颗星评分)实例代码
Dec 14 Javascript
javascript 网页进度条简单实例
Feb 22 Javascript
Vue 2.0在IE11中打开项目页面空白的问题解决
Jul 16 Javascript
解决Mac安装thrift因bison报错的问题
May 17 Javascript
vue自动添加浏览器兼容前后缀操作
Aug 13 Javascript
基于JS实现操作成功之后自动跳转页面
Sep 25 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
PHP 程序员的调试技术小结
2009/11/15 PHP
PHP中如何实现常用邮箱的基本判断
2014/01/07 PHP
PHP empty函数报错解决办法
2014/03/06 PHP
Win7下手动安装apache2.2、php5.4笔记
2015/04/03 PHP
yii2中的rules 自定义验证规则详解
2016/04/19 PHP
jQuery 源码分析笔记(6) jQuery.data
2011/06/08 Javascript
一个可拖拽列宽表格实例演示
2012/11/26 Javascript
js异步加载的三种解决方案
2013/03/04 Javascript
javascript处理表单示例(javascript提交表单)
2014/04/28 Javascript
JavaScript DOM基础
2015/04/13 Javascript
js正则表达式中exec用法实例
2015/07/23 Javascript
JS数组操作(数组增加、删除、翻转、转字符串、取索引、截取(切片)slice、剪接splice、数组合并)
2016/05/20 Javascript
Javascript之深入浅出prototype
2017/02/06 Javascript
浅谈jQuery的bind和unbind事件(绑定和解绑事件)
2017/03/02 Javascript
详解JSONObject和JSONArray区别及基本用法
2017/10/25 Javascript
Vuex入门到上手教程
2018/06/20 Javascript
Vue动态控制input的disabled属性的方法
2018/06/26 Javascript
解决vue中修改了数据但视图无法更新的情况
2018/08/27 Javascript
vue全局自定义指令-元素拖拽的实现代码
2019/04/14 Javascript
JavaScript 面向对象程序设计详解【类的创建、实例对象、构造函数、原型等】
2020/05/12 Javascript
vue项目打包为APP,静态资源正常显示,但API请求不到数据的操作
2020/09/12 Javascript
利用Python破解斗地主残局详解
2017/06/30 Python
遗传算法python版
2018/03/19 Python
Python 将Matrix、Dict保存到文件的方法
2018/10/30 Python
对DataFrame数据中的重复行,利用groupby累加合并的方法详解
2019/01/30 Python
Python读取stdin方法实例
2019/05/24 Python
python 实现"神经衰弱"翻牌游戏
2020/11/09 Python
苹果香港官方商城:Apple香港
2016/09/14 全球购物
国外软件测试工程师面试题
2016/12/09 面试题
副厂长岗位职责
2014/02/02 职场文书
《雾凇》教学反思
2014/02/17 职场文书
《谁的本领大》教后反思
2014/04/25 职场文书
不服从上级领导安排的检讨书
2014/09/14 职场文书
乡镇镇长个人整改措施
2014/10/01 职场文书
质量整改报告范文
2014/11/08 职场文书
教你怎么用Python监控愉客行车程
2021/04/29 Python