实例详解-类(二)
 
//===给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学习笔记-实例详解-类(二)的更多相关文章

  1. JavaScript学习笔记-实例详解-类(一)

    实例详解-类(一): //每个javascript函数(除了bind())都自动拥有一个prototype对象// 在未添加属性或重写prototype对象之前,它只包含唯一一个不可枚举属性const ...

  2. [CSS3] 学习笔记-选择器详解(二)

    1.选择器first-child.last-child.nth-child和nth-last-child 利用first-child.last-child.nth-child和nth-last-chi ...

  3. Java程序猿的JavaScript学习笔记(10—— jQuery-在“类”层面扩展)

    计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...

  4. Javascript学习笔记三——操作DOM(二)

    Javascript学习笔记 在我的上一个博客讲了对于DOM的基本操作内容,这篇继续巩固一下对于DOM的更新,插入和删除的操作. 对于HTML解析的DOM树来说,我们肯定会时不时对其进行一些更改,在原 ...

  5. Angular6 学习笔记——路由详解

    angular6.x系列的学习笔记记录,仍在不断完善中,学习地址: https://www.angular.cn/guide/template-syntax http://www.ngfans.net ...

  6. Angular6 学习笔记——组件详解之组件通讯

    angular6.x系列的学习笔记记录,仍在不断完善中,学习地址: https://www.angular.cn/guide/template-syntax http://www.ngfans.net ...

  7. Angular6 学习笔记——组件详解之模板语法

    angular6.x系列的学习笔记记录,仍在不断完善中,学习地址: https://www.angular.cn/guide/template-syntax http://www.ngfans.net ...

  8. Android学习笔记-Dialog详解

    1.对话框的使用 1.1AlertDialog的显示 简单对话框以及监听的设置:重点掌握三个按钮(也就是三上单词): PositiveButton(确认按钮);NeutralButton(忽略按钮) ...

  9. Spring MVC 3.0.5+Spring 3.0.5+MyBatis3.0.4全注解实例详解(二)

    在上一篇文章中我详细的介绍了如何搭建maven环境以及生成一个maven骨架的web项目,那么这章中我将讲述Spring MVC的流程结构,Spring MVC与Struts2的区别,以及例子中的一些 ...

随机推荐

  1. tomcat实现ServletContext的addListener方法的源码解说(原创)

    tomcat 8.0.36 知识点: 动态监听器有七类: ServletContextAttributeListener ServletRequestListener ServletRequestAt ...

  2. Anliven - 解决问题的一些方法

    How to resolve the problem? 获取基本的相关信息(后续处理问题的基础)  在怎样的背景环境下?发生了怎样的问题? 如果无法清楚地辨别或陈述问题的基本信息,那么,此时要面对的将 ...

  3. 前端开发教程:使用 CSS3 Transforms 构建圆形导航

    在本教程中我将告诉你如何使用 CSS 变换来创建圆形导航.教程逐一讲解实现这个样式将要涉及一些基本的数学知识并配合 CSS 变换来创建这些样式.不过不用担心,这里用到的数学知识真的是很简单的.教程使用 ...

  4. FindBugs使用

    FindBugs简介: FindBugs是一个开源的eclipse 代码检查工具,是一种白盒静态自动化测试工具: 它可以简单高效全面地帮助我们发现程序代码中存在的bug,bad smell,以及潜在隐 ...

  5. mysql插入日期 vs oracle插入日期

    今天做oracle日期插入的时候突然开始疑惑日期是如何插入的. 用框架久了,反而不自己做简单的工作了.比如插入. 通常,新建一个表对象,然后绑定数据,前端form提交,后端getModel后直接mod ...

  6. 25套用于 Web UI 设计的免费 PSD 网页元素模板

    Web 元素是任何网站相关项目都需要的,质量和良好设计的元素对于设计师来说就像宝贝一样.如果您正在为您的网站,博客,Web 应用程序或移动应用程序寻找完美设计的网页元素,那么下面这个列表会是你需要的. ...

  7. 用Latex写学术论文: IEEE Latex模板和文档设置(\documentclass)

    1.可以在博客园中使用latex代码输出公式,以后再以不用复制图片粘贴啦: http://www.cnblogs.com/cmt/p/3279312.html 例如以下代码两边加上 $ 符号后 x(k ...

  8. 从设计到开发,硅谷技术专家教你做“声控”APP

    编者:本文为携程机票研发部技术专家祁一鸣在携程技术微分享中的分享内容,关注携程技术中心微信公号ctriptech,获知更多一手干货. [携程技术微分享]是携程技术中心推出的线上公开分享课程,每月1-2 ...

  9. git clone 失败问题解决方案

    第一次从github上通过终端pull项目,出现了上述问题.询问了后台,才知道原来是电脑公钥(publickey)未添加至github,所以无法识别. 因而需要获取本地电脑公钥,然后登录github账 ...

  10. 【转载】ASP.NET MVC Web API 学习笔记---联系人增删改查

    本章节简单介绍一下使用ASP.NET MVC Web API 做增删改查.目前很多Http服务还是通过REST或者类似RESP的模型来进行数据操作的.下面我们通过创建一个简单的Web API来管理联系 ...