读书笔记----javascript类和模块
2016-03-24 19:50
232 查看
构造函数时用来初始化新创建的对象的,使用new关键字来初始化这个对象。使用new调用构造函数会自动创建一个新对象,因此构造函数本身只需要初始化这个新对象即可。
调用构造函数,构造函数的prototype属性被用做新对象的原型。所以通过构造函数创建的对象都继承一个相同的对象,他们都是同一个类的成员。
原型对象是类的唯一标识,当且仅当两个对象继承同一个原型对象是,它们才是同一个类的实例。
r instanceof Range//如果r继承自Range.prototype,则返回true
instanceof运算符并不会检查r是否由Range构造函数初始化来的,只会检查r是否继承自Range.prototype
每个javscript函数都拥有一个prototype属性,这个属性的值是一个对象,这个对象包含唯一一个不可枚举的属性constructor.
var p=F.prototype;//这是F相关联的原型对象
var c=p.constructor;//这是与原型相关联的函数
c===F //true 对于任意函数F.prototype.constructor==F
对象继承的constructor均指代它们的构造函数
var 0=new F();//提供F的一个对象
o.constructor===F //true constructor属性指代这个类
构造函数对象:为javascript的类定义了名字,任何添加到这个构造函数对象中的属性都是类字段和类方法
原型对象:属性被类的所有实例所继承,如果原型对象的属性值是函数的话,这个函数就作为类的实例方法来调用
实例对象:类的每个实例都是一个独立的对象
定义类的步骤:第一步先定义一个构造函数,并设置初始化新对象的实例属性
第二步给构造函数prototype对象定义实例方法
第三步给构造函数定义类字段和类属性
js中的原型继承机制是动态的,对象从原型继承属性,如果创建对象之后原型的属性发生改变,也会影响到继承这个原型的所有实例对象。
检测对象类的技术 instanceof isPrototypeOf constructor
instanceof检测对象继承关系,而不是检测创建对象的构造函数
isPrototypeOf()检测对象原型链上是否存在某个特定的原型对象
这两种方法的缺点:无法通过对象获得类名,只能检测对象是否属于指定的类名。在多个执行上下文中存在构造函数的多个副本的时候,检测结果出错。
辅助构造函数
如果O是类B的实例,B是A 的子类,那么O一定从A中继承了属性。为此首先确保B的原型对象继承自A的原型对象
B.prototype=inherit(A.prototype); //子类派生自父类
B.prototype.constructor=B; //重载继承来的constructor属性
这是创建子类的关键,如果不这样做,原型对象仅仅是一个普通对象,它只继承Object.prototype。
Object.preventExtensions()可以将对象设置为不可扩展的,不能为对象添加新的属性
Object.seal()除了阻止用户给对象添加新属性,还能将当前已有的属性设置为不可配置。
//range,js 实现一个能表示值的范围的类 function range(from,to){ //使用inherit()创建对象,这个对象继承下面定义的原型对象 var r=inherit(range.methods);//创建一个对象r,继承原型对象range.methods //定义起始位置和结束为止,这两个属性是非共享的不可继承的,每个对象都拥有唯一的属性 r.from=from; r.to=to; return r;//返回创建的新对象 } //原型对象的定义方法,这些方法为每个范围对象继承 range.methods={ includes:function (x){ return this.from<=x&&x<=this.to; }, //对于范围内的每个整数都调用一次f 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=range(1,3);//穿件一个范围对象 r.includes(2);//true 2在这个范围内 r.foreach(console.log);//输出1 2 3 console.log(r);//输出(1...3) // form to都是非共享的,不可继承的,但是range.methods中定义的可共享的,可继承的方法 //都用到了from和to,而且使用了this关键字。任何类的方法都可以通过this读取对象的属性
这里写代码片
调用构造函数,构造函数的prototype属性被用做新对象的原型。所以通过构造函数创建的对象都继承一个相同的对象,他们都是同一个类的成员。
//使用构造函数定义范围类 function Range(from,to){ //定义构造函数就是定义类,并且类的首字母大写 this.from=from; this.to=to; } Range.prototype={ //Range()构造函数调用会自动使用Range.prototype作为新的Range对象原形 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=range(1,3); r.includes(2); r.foreach(console.log); console.log(r); //上述构造函数定义类,定义的Range类使用它自身的一个对象重写预定义的Range.prototype对象。 //这个心定义的原型对象不含有constructor属性,因此Range类实例也不含有constructor属性
原型对象是类的唯一标识,当且仅当两个对象继承同一个原型对象是,它们才是同一个类的实例。
r instanceof Range//如果r继承自Range.prototype,则返回true
instanceof运算符并不会检查r是否由Range构造函数初始化来的,只会检查r是否继承自Range.prototype
每个javscript函数都拥有一个prototype属性,这个属性的值是一个对象,这个对象包含唯一一个不可枚举的属性constructor.
//显式给原型添加一个构造函数 Range.prototype={ constructor:Range, // 显式设置构造函数反向引用 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 p=F.prototype;//这是F相关联的原型对象
var c=p.constructor;//这是与原型相关联的函数
c===F //true 对于任意函数F.prototype.constructor==F
对象继承的constructor均指代它们的构造函数
var 0=new F();//提供F的一个对象
o.constructor===F //true constructor属性指代这个类
//使用预定义的原型对象,预定义的原型对象包含constructor属性,然后依次给原型对象添加方法 //扩展预定义的Range.prototype对象,这样就自动创建Range.prototype.constructor属性 Range.prototype.includes=function (x){ return this.from<=x&&x<=this.to;}; Range.prototype.foreach=function (f){ for (var x=Math.ceil(this.from);x<=this.to;x++) f(x); }; Range.prototype.toString=function(){ return "("+this.from+"..."+this.to+")"; };
构造函数对象:为javascript的类定义了名字,任何添加到这个构造函数对象中的属性都是类字段和类方法
原型对象:属性被类的所有实例所继承,如果原型对象的属性值是函数的话,这个函数就作为类的实例方法来调用
实例对象:类的每个实例都是一个独立的对象
定义类的步骤:第一步先定义一个构造函数,并设置初始化新对象的实例属性
第二步给构造函数prototype对象定义实例方法
第三步给构造函数定义类字段和类属性
//定义一个简单的类函数 function defineClass( constructor, //用来设置实例属性的函数 methods, //实例的方法,复制至原型中 statics //类属性,复制到构造函数中 ) { if (methods) extend(constructor.prototype,methods); if (statics) extend(constructor,statics); return constructor; } //Range 类的实现 var SimpleRange= defineClass (function (f,t) {this.f=f;this.t=t;}, { includes:function (x){return this.f<=x&&x<=this.t;}, toString: function(){ return this.f+"..."+this.t} }, {upto: function(t) {return new SimpleRange(0,t);}} );
js中的原型继承机制是动态的,对象从原型继承属性,如果创建对象之后原型的属性发生改变,也会影响到继承这个原型的所有实例对象。
检测对象类的技术 instanceof isPrototypeOf constructor
instanceof检测对象继承关系,而不是检测创建对象的构造函数
isPrototypeOf()检测对象原型链上是否存在某个特定的原型对象
这两种方法的缺点:无法通过对象获得类名,只能检测对象是否属于指定的类名。在多个执行上下文中存在构造函数的多个副本的时候,检测结果出错。
辅助构造函数
//辅助构造函数 function SetFromArray(a){ //将a的元素作为参数传入 Set.apply(this,a); } //设置原型,以便SetFormArray能够创建Set实例 SetFromArray.prototype=Set.prototype; var s=new SetFromArray([1,2,3]); s instanceof Set //true
如果O是类B的实例,B是A 的子类,那么O一定从A中继承了属性。为此首先确保B的原型对象继承自A的原型对象
B.prototype=inherit(A.prototype); //子类派生自父类
B.prototype.constructor=B; //重载继承来的constructor属性
这是创建子类的关键,如果不这样做,原型对象仅仅是一个普通对象,它只继承Object.prototype。
Object.preventExtensions()可以将对象设置为不可扩展的,不能为对象添加新的属性
Object.seal()除了阻止用户给对象添加新属性,还能将当前已有的属性设置为不可配置。
//定义一个复数类 function Complex(real,imaginary){ if (isNaN(real)||isNaN(imaginary)) throw new TypeError(); this.r=real; this.i=imaginary; } Complex.prototype.add=function(that){ return new Complex(this.r+that.r,this.i+that.i); } Complex.prototype.equals=function(that){ return that!=null&& //必须有定义且不能是null that.constructor===Complex&& //必须是Complex实例 this.r===that.r&&this.i===that.i; //包含相同的值 } //定义对复数运算有帮助的类字段,他们都是常量 Complex.ZERO=new Complex(0,0); Complex.ONE=new Complex(1,0);
function typeAndValue(x){ if (x==null) return " ";// null undefined 没有构造函数 switch (x.constructor){ case Number: return "Number:"+x;//处理原始类型 case String: return "String:' "+x+" '" ; case Date:return "Date: "+x; //处理内置对象 case RegExp: return "Regexp: "+x; case Complex:return "Complex: "+x;//定义自定义类型 } } //case后的表达式都是函数,如果改为typeof 运算符或获取到对象的class属性的话,应当改为字符串
相关文章推荐
- EventUtil 整理
- 初识 js Cookies
- extjs6 desktop 桌面多主题切换
- javascript实现轮播图
- Atitit.js this错误指向window的解决方案
- Atitit.js this错误指向window的解决方案
- Atitit.js this错误指向window的解决方案
- js转换时间戳
- js学习内容的整理
- [javascript] 模拟通讯薄锚点跳转
- Javascript笔记《三》之作用域
- Javascript笔记《二》之命名冲突
- 工作记录1:extJS-checkboxgroup复选框和combo联动
- js中单引号和双引号
- JS去掉文字中的html代码段
- KMP算法学习笔记(二)
- extjs 表格单元格 垂直居中对齐
- JavaScript之基础-5 JavaScript 函数
- JavaScript中对变量和函数声明的提前
- JS中比較2个字符串内元素的不同(字符1, 字符2, 分隔符可选)