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插件实现图片延迟加载技术详细说明
Mar 12 Javascript
JsDom 编程小结
Aug 09 Javascript
javascript函数以及基础写法100多条实用整理
Jan 13 Javascript
tuzhu_req.js 实现仿百度图片首页效果
Aug 11 Javascript
Javascript的this用法
Jan 16 Javascript
微信小程序开发入门基础教程
Apr 19 Javascript
JavaScript实现的超简单计算器功能示例
Dec 23 Javascript
Vue 换肤的示例实践
Jan 23 Javascript
JSON的parse()方法介绍
Jan 31 Javascript
JavaScript console的使用方法实例分析
Apr 28 Javascript
详解JavaScript 异步编程
Jul 13 Javascript
vue3自定义dialog、modal组件的方法
Jan 04 Vue.js
微信小程序实现团购或秒杀批量倒计时
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中常用字符串处理代码片段整理
2011/11/07 PHP
zf框架的zend_cache缓存使用方法(zend框架)
2014/03/14 PHP
destoon二次开发常用数据库操作
2014/06/21 PHP
PHP获取音频文件的相关信息
2015/06/22 PHP
深入浅析用PHP实现MVC
2016/03/02 PHP
两个DIV等高的JS的实现代码
2007/12/23 Javascript
JavaScript 组件之旅(四):测试 JavaScript 组件
2009/10/28 Javascript
javascript 日期常用的方法
2009/11/11 Javascript
解析window.open的使用方法总结
2013/06/19 Javascript
jquery的ajax简单结构示例代码
2014/02/17 Javascript
js实现发送验证码后的倒计时功能
2015/05/28 Javascript
初步认识JavaScript函数库jQuery
2015/06/18 Javascript
javascript实现连续赋值
2015/08/10 Javascript
APP中javascript+css3实现下拉刷新效果
2016/01/27 Javascript
浅析创建javascript对象的方法
2016/05/13 Javascript
jQuery实现背景弹性滚动的导航效果
2016/06/01 Javascript
websocket+node.js实现实时聊天系统问题咨询
2017/05/17 Javascript
微信小程序实现的一键拨号功能示例
2019/04/24 Javascript
基于JQuery实现页面定时弹出广告
2020/05/08 jQuery
JS实现多选框的操作
2020/06/24 Javascript
Django框架之登录后自定义跳转页面的实现方法
2019/07/18 Python
基于Python制作一副扑克牌过程详解
2020/10/19 Python
印度尼西亚最好的小工具在线商店:Erafone.com
2019/03/26 全球购物
韩语专业本科生求职信
2013/10/01 职场文书
七年级英语教学反思
2014/01/15 职场文书
中药学自荐信
2014/06/15 职场文书
乡领导班子四风问题对照检查材料
2014/09/25 职场文书
二年级上册数学教学计划
2015/01/20 职场文书
实习指导老师意见
2015/06/04 职场文书
感恩教师主题班会
2015/08/12 职场文书
导游词之南京莫愁湖公园
2019/11/13 职场文书
Python基于百度API识别并提取图片中文字
2021/06/27 Python
Python requests用法和django后台处理详解
2022/03/19 Python
Python中生成随机数据安全性、多功能性、用途和速度方面进行比较
2022/04/14 Python
通过feDisplacementMap和feImage实现水波特效
2022/04/24 HTML / CSS
错误码NET::ERR_CERT_DATE_INVALID证书已过期解决方法?
2022/07/07 数码科技