实例详解-类(二)
 
//===给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. Foundation 5 发布!最先进的响应式前端框架

    数以百万计的设计师和工程师采用 Foundation 作为他们的产品和网站设计的前端框架.Foundation 是第一个响应式.语义化和移动优先的开源框架.最新发布的 Foundation 5 是最先 ...

  2. 设计前沿:25个设计师向您展示 iOS 7 界面

    我们中的许多人都对新发布的 iOS 7 用户界面有点失望.扎眼的颜色搭配,难看的图标和可疑的设计决策,导致很多的设计师在 Dribbble 和 Behance 等社交网站分享自己对 iOS 界面设计的 ...

  3. 高性能ORM 框架之 MySqlSugar

    mysql 3.X API地址:  http://www.cnblogs.com/sunkaixuan/p/5987308.html MySqlSugar 1.5 API 一.介简 SqlSugar ...

  4. JS魔法堂:判断节点位置关系

    一.前言 在polyfill querySelectorAll 和写弹出窗时都需要判断两个节点间的位置关系,通过jQuery我们可以轻松搞定,但原生JS呢?下面我将整理各种判断方法,以供日后查阅. 二 ...

  5. IOS开发技巧快速生成二维码

    随着移动互联网的发展,二维码应用非常普遍,各大商场,饭店,水果店 基本都有二维码的身影,那么ios中怎么生成二维码呢? 下面的的程序演示了快速生成二维码的方法: 在ios里面要生成二维码,需要借助一个 ...

  6. Hibernate —— Hibernate 配置文件

    1.Hibernate 配置文件主要用于配置**数据库连接**和 Hibernate 运行时所需的**各种属性**. 2.每一个 Hibernate 配置文件对应一个 Configuration 对象 ...

  7. html的<!DOCTYPE>标签初窥

    <!DOCTYPE>标签必须放在整个html文档的第一行,之后一行就是从<html>标签开始,所有浏览器都支持<!DOCTYPE>标签. <!DOCTYPE& ...

  8. 选择排序---堆排序算法(Javascript版)

    堆排序分为两个过程: 1.建堆. 堆实质上是完全二叉树,必须满足:树中任一非叶子结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字. 堆分为:大根堆和小根堆,升序排序采用大根堆,降序排序 ...

  9. RDLC报表打印

    如果你的报表能正常显示,会看到RDLC工具条下的打印图标: 如果在客户端,第一次去点击此铵钮,如果当前操作者没有管理权限,会提示: Unable to load client print contro ...

  10. Nancy 学习-身份认证(Forms authentication) 继续跨平台

    开源 示例代码:https://github.com/linezero/NancyDemo 上篇讲解Nancy的Basic Authentication,现在来学习Nancy 的Forms身份认证. ...