JavaScript学习笔记-实例详解-类(二)
//===给Object.prototype添加只读\不可枚举\不可配置的属性objectId
(function(){
Object.defineProperty(Object.prototype,'objectId',{
get:idGetter, //读取objectId时直接调用idGetter函数
enumerable:false,
configurable:false
});
function idGetter(){
if(!(idprop in this)) { //检测是否存在idprop
if (!Object.isExtensible(this)) {
throw Error('can not define id for nonextensible objects');
}
Object.defineProperty(this, idprop, {
value: nextid++,
writable: false,
enumerable: false,
configurable: false
});
}
return this(idprop);
}
var idprop = '|**objectid**|'; //假设这个属性没用到
var nextid = 1;
}());
//====创建一个不可变得类,它的属性,方法都是不可变得===
//===Object.defineProperty()和Object.defineProperties()可以用来创建新属性,也可以修改已有属性的特性。
// 更改或设置属性描述时,未指定的属性保持已有值,默认是false
function Range(from,to){
var props = {
from:{value:from,enumerable:true,writable:false,configurable:false},
to:{value:to,enumerable:true,writable:false,configurable:false}
};
if(this instanceof Range) Object.defineProperties(this,props);
else return Object.create(Range.prototype,props);
}
//添加不可变方法,除了value,其它都是false
Object.defineProperties(Range.prototype,{
includes:{value:function(x){return this.from<=x && x<=this.to;}},
foreach:{value:function(f){for(var x=Math.ceil(this.from);x<=this.to;x++) f(x)}}
});
//=====设置属性描述的工具函数========
function freezeProps(o){
var props = (arguments.length == 1) //如果只有一个参数
?Object.getOwnPropertyNames(o) //使用所有属性
:Array.prototype.slice.call(arguments,1); //否则传入了指定名字的属性
props.forEach(function(n){
//if(!Object.getOwnPropertyDescriptor(o,n).configurable) return; //忽略不可配置属性
Object.defineProperty(o,n,{writable:false,configurable:false});
});
return o;
}
function hideProps(o){
var props = (arguments.length == 1)
?Object.getOwnPropertyNames(o)
:Array.prototype.slice.call(arguments,1);
props.forEach(function(n){
//if(!Object.getOwnPropertyDescriptor(o,n).configurable) return;
Object.defineProperty(o,n,{enumerable:false});
});
return o;
}
//==使用以上工具函数
function Range1(from,to){
this.from = from;
this.to = to;
freezeProps(this);
}
Range1.prototype = hideProps({
constructor:Range1,
includes:function(x){return this.from<=x && x<= this.to;},
foreach:function(f){for(var x=Math.ceil(this.from);x<=this.to;x++) f(x)},
toString:function(){return '('+this.from+'...'+this.to+')'}
});
var r = new Range1(4,6);
r.from = 1;
r.to = 8;
console.log(r.from); //4 无法修改
console.log(r.to);
//==========封装对象的私有状态(构造函数的属性)======
function Range2(from,to){
function getFrom(){return from;}
function getTo(){return to;}
function setFrom(f){ from = f;}
function setTo(t){ to = t;}
Object.defineProperties(this,{
from:{get:getFrom,set:setFrom,enumerable:true,configurable:false},
to:{get:getTo,set:setTo,enumerable:true,configurable:false}
});
}
Range2.prototype = hideProps({
constructor:Range1,
includes:function(x){return this.from<=x && x<= this.to;},
foreach:function(f){for(var x=Math.ceil(this.from);x<=this.to;x++) f(x)},
toString:function(){return '('+this.from+'...'+this.to+')'}
});
JavaScript学习笔记-实例详解-类(二)的更多相关文章
- JavaScript学习笔记-实例详解-类(一)
实例详解-类(一): //每个javascript函数(除了bind())都自动拥有一个prototype对象// 在未添加属性或重写prototype对象之前,它只包含唯一一个不可枚举属性const ...
- [CSS3] 学习笔记-选择器详解(二)
1.选择器first-child.last-child.nth-child和nth-last-child 利用first-child.last-child.nth-child和nth-last-chi ...
- Java程序猿的JavaScript学习笔记(10—— jQuery-在“类”层面扩展)
计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...
- Javascript学习笔记三——操作DOM(二)
Javascript学习笔记 在我的上一个博客讲了对于DOM的基本操作内容,这篇继续巩固一下对于DOM的更新,插入和删除的操作. 对于HTML解析的DOM树来说,我们肯定会时不时对其进行一些更改,在原 ...
- Angular6 学习笔记——路由详解
angular6.x系列的学习笔记记录,仍在不断完善中,学习地址: https://www.angular.cn/guide/template-syntax http://www.ngfans.net ...
- Angular6 学习笔记——组件详解之组件通讯
angular6.x系列的学习笔记记录,仍在不断完善中,学习地址: https://www.angular.cn/guide/template-syntax http://www.ngfans.net ...
- Angular6 学习笔记——组件详解之模板语法
angular6.x系列的学习笔记记录,仍在不断完善中,学习地址: https://www.angular.cn/guide/template-syntax http://www.ngfans.net ...
- Android学习笔记-Dialog详解
1.对话框的使用 1.1AlertDialog的显示 简单对话框以及监听的设置:重点掌握三个按钮(也就是三上单词): PositiveButton(确认按钮);NeutralButton(忽略按钮) ...
- Spring MVC 3.0.5+Spring 3.0.5+MyBatis3.0.4全注解实例详解(二)
在上一篇文章中我详细的介绍了如何搭建maven环境以及生成一个maven骨架的web项目,那么这章中我将讲述Spring MVC的流程结构,Spring MVC与Struts2的区别,以及例子中的一些 ...
随机推荐
- 【目录】Newlife XCode组件相关文章目录
本博客所有文章分类的总目录链接:本博客博文总目录-实时更新 1.Newlife XCode组件相关文章目录 1.Newlife XCode组件资源目录汇总[2013年版] 2.Newlife ...
- 百度地图JavaScript API覆盖物旋转时出现偏移
在项目中,调用百度地图JavaScript API,做覆盖物的旋转再添加到地图上,结果出现偏移了. 调试过程中的效果图: 发现图片的旋转并不是按车子的中心来的,而是之外的一个点.最后发现犯了一个很细节 ...
- 【圣诞特献】Web 前端开发精华文章推荐【系列二十一】
<Web 前端开发精华文章推荐>2013年第九期(总第二十一期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各种增强网站用户体验的 jQuery 插件,展示前沿的 HTML5 和 ...
- [New Portal]Windows Azure Virtual Machine (13) 在本地使用Hyper-V制作虚拟机模板,并上传至Azure (3)
<Windows Azure Platform 系列文章目录> 本章介绍的内容是将本地Hyper-V的VHD,上传到Azure数据中心,作为自定义的虚拟机模板. 注意:因为在制作VHD的最 ...
- Elasticsearch DSL中Query与Filter的不同
Elasticsearch支持很多查询方式,其中一种就是DSL,它是把请求写在JSON里面,然后进行相关的查询. 举个DSL例子 GET _search { "query": { ...
- DedeCMS学习
也许有些读者并不了解dedecms,这里简单介绍一下:DedeCMS是一个自由和开放源码的内容管理系统,它是一个可以独立使用的内容发布系统(CMS).织梦内容管理系统(DedeCms) 以简单.实用. ...
- Entity Framework基础01
学习了ADO.NET的相关知识,掌握了它对数据库表的基本操作,但是实际在开发项目应用中微软为我们开发ef这个ORM,使用它可以很方便的利用ADO.NET来操作DBMS,使得我们开发项目的着重点放在业务 ...
- 数论 - Funny scales(SPOJ - SCALE)
Funny scales Problem's Link ------------------------------------------------------------------------ ...
- 能不能用javascript实现素数求和问题呢?
先自己试试吧 好吧,下面这段代码用了别人所说的最笨的方法,身为小白的我只能呵呵.待会再尝试用其他算法. <!DOCTYPE html> <html lang="en&quo ...
- log4net的配置详解
log4net是一款优秀的第三方日志框架,可以很容易的加载到开发项目中(引用log4net的dll,再配置些基本参数即可),帮助程序员把日志信息输出到各种不同的目标,常见的有文本.数据库.window ...