语法

Object.defineProperty(obj, prop, descriptor)

参数

obj
要在其上定义属性的对象。
prop
要定义或修改的属性的名称。
descriptor
将被定义或修改的属性描述符。

返回值

被传递给函数的对象。

使用说明:

我们一般给一个对象创建一个新的属性时,大部分采用的都是如下方式:

var obj = {};
obj.key = "Hello"

但是这种创建方式的属性,其值可被修改,可被遍历等等。 如果想创建隐藏属性(使用for in 无法遍历出来)

或者想创建一个只读属性(不可写入),使用这种方式就不可取了。在ES6中,有一个叫做Symbol类型的东西

这个东西可以人为的定义它是否可写,可枚举,可重配置等等,而定义这个Symbol的方法则是Object对象的 defineProperty

这里可以将Symbol理解为带特殊技能的属性。 我们可以为一个对象,使用defineProperty方法来定义一个带红蓝buff的属性

先来说说属性描述符,由名称可知是用来描述一个属性具有什么特点用的,属性描述符分为两类: 数据描述符存取描述符

数据描述符表示一个具有值的属性,该值可能只读,可能可写

存储描述符表示一个具有对数据进行存取操作的属性。

一个属性只能为以上两种类别中的一个,不能同时是两者

下面是一些上面两个描述符可选的键值:

configurable:  是否允许改变描述符,是否允许删除属性,默认false

enumerable:   是否允许被枚举(for in), 默认false

writeable:   是否可写,默认false

value:    设定数据描述符的value值,默认是undefine

get:     设定存储描述符的getter方法,默认undefine

set:     设定存储描述符的setter方法,默认undefine

注意: configurable enumerable 这两个描述键值 是数据描述符 与 存储描述符 共有的

writeable 和 value 是数据描述符独有的, 而set 和 get方法是存储描述符独有的,另外

这些选项不一定是自身的属性,也需要考虑继承,为确保留有默认值,需要冻结之前的

Object.prototype,或者将__proto__属性指向null

说了那么多概念性的东西,下面来实战练习一下吧

任务一: 创建一个带有只读属性的对象

var o = {};

Object.defineProperty(o, "myName", {
value: "孙悟空",
writeable: false //不允许写,只读的
}); document.write(o.myName); //孙悟空 //尝试改变属性 o.myName = "猪八戒"; //这里不会报错,但是会抛出readonly
document.write(o.myName); //孙悟空

任务二: 创建一个带有"隐藏"属性的对象

var o = {};

Object.defineProperty(o, "myName", {
value: "孙悟空",
enumerable: false //不允许被枚举出来
}); //通过普通方式创建其他属性
o.myAge = 33;
o.myAddress = "China"; //枚举对象所有变量
for(var i in o){
document.write(i +":"+ o[i] + "<br>");
} //输出结果:
//myAge: 33
//myAddress: China //虽然无法遍历出来,但是依然是可以访问的
document.write(o.myName); //孙悟空

任务三:创建一个带有存储描述符的属性对象

var p;              //稍后使用存储描述符对他进行读写操作
var o = {}; Object.defineProperty(o, "b", { //属性名为b
get: function(){
return p; //取全局变量
}, set: function(value){
p = value; //写全局变量
}, enumerable: true, //可遍历
configurable: true //可修改
}); o.b = 38; //看起来像是直接赋值,其实是调用了set方法赋值 document.write(p); //38, 因为get方法读写的对象是全局变量

存储描述符,给人感觉像是对 对象的属性进行读写操作,但其实背后可能是对其他变量的读写

操作,因为可以人为的定义读写操作执行的函数 set/get ,所以我们就可以实现读写时实现自己

想要的功能,比如数据类型判断等等,如果对存储描述符还是不太理解,可以看看下面两段代码

实现一个自存档的属性

function Archiver() {
var temperature = null;
var archive = []; Object.defineProperty(this, 'temperature', {
get: function() {
console.log('get!');
return temperature;
},
set: function(value) {
temperature = value;
archive.push({ val: temperature });
}
}); this.getArchive = function() { return archive; };
} var arc = new Archiver();
arc.temperature; // 'get!'
arc.temperature = 11;
arc.temperature = 13;
arc.getArchive(); // [{ val: 11 }, { val: 13 }]

第二段

var pattern = {
get: function () {
return 'I alway return this string,whatever you have assigned';
},
set: function () {
this.myname = 'this is my name string';
}
}; function TestDefineSetAndGet() {
Object.defineProperty(this, 'myproperty', pattern);
} var instance = new TestDefineSetAndGet();
instance.myproperty = 'test'; // 'I alway return this string,whatever you have assigned'
console.log(instance.myproperty);
// 'this is my name string'
console.log(instance.myname);

对于configurable的效果,大家可能还有疑问,可以阅读下面这段代码,自己动手试试

var o = {};
Object.defineProperty(o, "a", { get : function(){return 1;},
configurable : false } ); // throws a TypeError
Object.defineProperty(o, "a", {configurable : true});
// throws a TypeError
Object.defineProperty(o, "a", {enumerable : true});
// throws a TypeError (set was undefined previously)
Object.defineProperty(o, "a", {set : function(){}});
// throws a TypeError (even though the new get does exactly the same thing)
Object.defineProperty(o, "a", {get : function(){return 1;}});
// throws a TypeError
Object.defineProperty(o, "a", {value : 12}); console.log(o.a); // logs 1
delete o.a; // Nothing happens
console.log(o.a); // logs 1

关于javascript中defineProperty的学习的更多相关文章

  1. javascript中的正则表达式学习

    一.前言 关于正则表达式自身的语法这里不做过多介绍(详情可参见http://www.php100.com/manual/unze.html),这里仅仅解释javascript中和正则表达式相关的几个方 ...

  2. JavaScript中的EcMAScript学习笔记

    一.Javascript概述(知道)    a.一种基于对象和事件驱动的脚本语言    b.作用: 给页面添加动态效果    c.历史: 原名叫做livescript.W3c组织开发的标准叫ECMAs ...

  3. JavaScript中 Promise的学习以及使用

    今天一个哥们发过来一段js代码,没看懂,就顺便学习了一下,代码如下  Promise.resolve('zhangkai').then(value => {console.log(value)} ...

  4. Javascript中Object常用方法学习

    1.Object.assign 函数(对象)(JavaScript) 将来自一个或多个源对象中的值复制到一个目标对象.语法: Object.assign(target, ...sources ); 此 ...

  5. JavaScript中NODE操作学习总结

    Node: 1.在 HTML DOM (文档对象模型)中,每个部分都是节点:    文档本身是文档节点     所有 HTML 元素是元素节点     所有 HTML 属性是属性节点     HTML ...

  6. javascript中的面向对象—— 学习1

    面向对象:Object Oriented(OO) 一切事物皆对象,通过面向对象的方式,将显示世界的事物抽象成对象,将显示世界中的关系抽象成类.继承,帮助人们实现对显示世界的抽象与数字建模:--百科 一 ...

  7. javascript中this的学习总结

    在开发中,this多使用在function函数中,也正是由于调用function的对象的不同,才导致了this的指向不同.需要明白(1).function也是对象:(2).function执行时是在某 ...

  8. javascript中的事件学习总结

    一.实例: 一段用js实现的固定边栏滚动特效代码(跨浏览器使用): 二.总结: 由于事件处理在不同浏览器之间存在差异(主要是要考虑ie8及以下浏览器的兼容性),所以在使用处理事件的方法之前,先要判断当 ...

  9. 前端学习 第六弹: javascript中的函数与闭包

    前端学习 第六弹:  javascript中的函数与闭包 当function里嵌套function时,内部的function可以访问外部function里的变量 function foo(x) {   ...

随机推荐

  1. centos7环境安装rabbitMQ

    使用专业的消息队列产品rabbitmq之centos7环境安装 http://www.cnblogs.com/huangxincheng/p/6006569.html [源码安装,适用GNOME + ...

  2. 快播王欣发布匿名IM社交软件“马桶MT”

    2019年1月14日,快播王欣推出了一款匿名IM社交软件——马桶MT,它的灵感像是来自于美国的匿名分享应用Secret(已关闭). 原快播创始人王欣近日在微博预告了其新公司云歌人工智能推出一款全新社交 ...

  3. 程序-代写(qq:928900200)

    CS 310 Programming Assignment 4 Due April 27, 2014 5:00 P.M. About 15 years in the future... The Mar ...

  4. 5 款最新的 jQuery 图片裁剪插件

    这篇文章主要介绍最新的 5 款 jQuery 图片裁剪插件,可以帮助你轻松的实现你网站需要的图像裁剪功能. Cropit Cropit 是一个 jQuery 插件,支持图像裁剪和缩放功能.Cropit ...

  5. OpenGL 获取当前屏幕坐标的三维坐标(gluUnProject使用例子 VS+glut)

    本例子参考于网络,并进行了一些修改,使用glut+vs2008来实现. 在鼠标点击处重新画一个旋转的红色立方体! 参考代码如下:  C++ Code  123456789101112131415161 ...

  6. Git 学习笔记--删除错误提交的commit

    如果不小心把错误的commit给commit了,可以对其进行撤销 1.使用git log查看commit日志,找到错误提交前一版本commit的哈希值; 2.使用git reset --hard co ...

  7. M0 M4时钟控制(一)

    时钟控制器为整个芯片提供时钟源,包括系统时钟和所有外围设备时钟.该控制器还通过单独时钟的开或关,时钟源选择和分频器来进行功耗控制.在CPU使能低功耗PDEN(CLK_PWRCTL[7]) 位和Cort ...

  8. File /hbase/.tmp/hbase.version could only be replicated to 0 nodes instead of minReplication (=1).

    File /hbase/.tmp/hbase.version could only be replicated to 0 nodes instead of minReplication (=1). 这 ...

  9. Unity Shader 景深效果

    效果 原理: 开启摄像机的深度模式,将深度保存到一张名为_CameraDepthTexture(Unity5.0之后才有)内置的纹理中. 如果深度在焦点范围内就用原图,否则就用模糊图. Shader: ...

  10. 拦截$.ajax方法实现登录过期登录

    jQuery(function ($) { var CreateLoginWindows = function (callback) { var h = 300; $('#CreateLoginWin ...