类和模块
每个js的对象都是属性的集合。相互之间没有联系。
js也能定义对象的类,让每个对象都共享某些属性。
类的成员或者实例包含一些属性,用来存放或者定义他们的状态。有些属性定义了其行为,(行为或者称为方法)
方法是类定义的,被所有的实例共享。
例如,用一个类来表示复数,同时定义了一些相关的复数运算,一个这个类的实例应当包含这个实例的状态,即包含复数的实部和虚部,同样还需要有行为,即方法,行为为复数的加减法运算
js中类的实现是基于原型继承机制的,如果两个实例都从同一个原型对象上继承了属性,
如果两个对象继承自同一原型,往往意味着由同一个构造函数创建并初始化。
js中的类和Java中的类不一样!!!!
好吧,彻底看不懂书了。。心累
那就大概搜索一下博客得了
https://www.cnblogs.com/TomXu/archive/2012/02/23/2353389.html
发现一个博客,先看看,再说,看样子写的很好,还出书了。
貌似写的很好
类和原型
js中类的所有实例对象都从同一个原型对象上继承属性
额。暂时到这,剩下的实在看不懂了。。
┑( ̄Д  ̄)┍
感觉好难。。。
真的很难
工厂方法
工厂是函数,产品是对象,通过制定其相关要求,批量产生对象,这样的函数为工厂方法
一个工厂方法的实例
// 一个工厂实例
function range(from, to) {
// 使用Object.create创建一个新的基于该函数原型链的一个对象
var r = Object.create(range);
// 存储着起始和结束位置
r.from = from;
r.to = to;
// 返回这个对象
return r;
}
好啦,一个工厂实例完成,试用一下这个工厂,用来加工生产一批对象
var f1 = range(324, 345);
undefined
f1;
Object { from: 324, to: 345 }
这样就灰常完美的创建的一个新的对象,并且这个对象是从324到345的
以上这个工厂能批量生产对象,只要制定其范围,就能批量完成
灰常方便
一个完整的工厂方法
// 一个工厂实例
function range(from, to) {
// 使用Object.create创建一个新的基于该函数原型链的一个对象
var r = Object.create(range.methods);
// 存储着起始和结束位置
r.from = from;
r.to = to;
// 返回这个对象
return r;
}
range.methods = {
// 如果在这个范围之内则返回true,否false
// 这个方法用于比较数字
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 + ')';
},
}
上方代码中,是基于range.methods方法为原型链进行创建的,所有创建的对象都基于这个原型,并都继承这个原型链
来,尝试一下这个函数
先创建一个变量,用于指向这个对象
var r = range(23,5464);
undefined
r;
Object { from: 23, to: 5464 }
然后~继续
继续使用其方法
r.includes;
function includes()
r.includes(2);
false
然后~继续
继续尝试第二个属性
r.foreach(console.log)
好吧(∩_∩)
浏览器崩溃了
o(≧口≦)o
输出太多了
js的性能太不好,经常崩溃,,无语
O__O “…
类和构造函数
// range.js 表示类的另外一种实现
// 一个构造函数,用以初始化新创建的范围对象
// 注意,这里并没有新建并返回一个对象,仅仅是将该对象初始化
function Range(from, to) {
// 这两个属性不在原型链中
this.from = from;
this.to = to;
}
// 添加Range类的原型链
Range.prototype = {
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(34, 45);
undefined
range = Range;
function Range()
var r = range(32, 43);
undefined
r;
undefined
ps 其中有一项约定,是一般情况下,类第一个字母大写,函数第一个字母小写,采用驼峰命名法,这个具有一定分辨
好吧,貌似这本书有点问题,估计是更新的原因,代码始终不通过,这点过
var r = new range(23,34);
undefined
r;
{…}
from: 23
to: 34
<prototype>: Object { includes: includes()
, foreach: foreach(), toString: toString()
}
r.includes(33);
true
书中和实际中的是,事实上js不会完成这一转换,估计在新版本中去掉了,全部代码如下
// range.js 表示类的另外一种实现
// 一个构造函数,用以初始化新创建的范围对象
// 注意,这里并没有新建并返回一个对象,仅仅是将该对象初始化
var range = function Range(from, to) {
// 这两个属性不在原型链中
this.from = from;
this.to = to;
}
// 添加Range类的原型链
range.prototype = {
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 + ')'; },
};
另外需要在总结一点,prototype和__proto__之间的关系,前者是加到该属性中,在继承时为继承的原型链,后者是继承的继承的,即父的父的关系的继承,一个是往上有一层,一个是两层,链如下
如果使用__proto__则如下
这两个有区别,不能会混为一谈,一个是往子添加原型,一个是往父添加原型。
试用基本木有问题,过
new的含义,new是创建一个空对象,并将其根据的对象的原型添加进入这个空对象的原型
![]()
如上图所示,其中根据new创建的对象的原型链是根据new的操作数来进行的。
b.constructor();
undefined
所以这样是能访问其new的函数的
ps含义constructor为构造器,真的贴近啊,实际上就是构造器,貌似有一本书是js的设计模式
前提条件是必须是对象,或者函数,或者数组
构造函数和类标识
当且仅当两个对象继承自同一原型对象的时候,这个两个才属于一个类的实例。
即两个构造函数创建的实例的prototype是指向同一个原型对象
当原型链修改的时候,其子不会发生改变
通过运算符instanceof来进行计算
b instanceof a;
false
constructor属性
对就是上文中的构造器。
依旧这一段代码
var range = function Range(from, to) {
// 这两个属性不在原型链中
this.from = from;
this.to = to;
}
// 添加Range类的原型链
range.prototype = {
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 + ')'; },
};
其中必须使用new,因为没有返回值,必须使用new,让其成为对象,而操作数为其原型
明天是js的Java式继承
https://www.iming.info/archives/463.html