资讯专栏INFORMATION COLUMN

类和模块 类和原型 工厂方法 构造函数 constructor

hedzr / 629人阅读

摘要:即两个构造函数创建的实例的是指向同一个原型对象当原型链修改的时候,其子不会发生改变通过运算符来进行计算属性对就是上文中的构造器。

类和模块
每个js的对象都是属性的集合。相互之间没有联系。
js也能定义对象的类,让每个对象都共享某些属性。
类的成员或者实例包含一些属性,用来存放或者定义他们的状态。有些属性定义了其行为,(行为或者称为方法)
方法是类定义的,被所有的实例共享。
例如,用一个类来表示复数,同时定义了一些相关的复数运算,一个这个类的实例应当包含这个实例的状态,即包含复数的实部和虚部,同样还需要有行为,即方法,行为为复数的加减法运算
js中类的实现是基于原型继承机制的,如果两个实例都从同一个原型对象上继承了属性,
如果两个对象继承自同一原型,往往意味着由同一个构造函数创建并初始化。
js中的类和Java中的类不一样!!!!
好吧,彻底看不懂书了。。心累
那就大概搜索一下博客得了
https://www.cnblogs.com/TomXu...
发现一个博客,先看看,再说,看样子写的很好,还出书了。
貌似写的很好

类和原型

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的
以上这个工厂能批量生产对象,只要制定其范围,就能批量完成
灰常方便

Math.ceil 天花板函数
一个完整的工厂方法
// 一个工厂实例
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
​
: 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/archiv...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96205.html

相关文章

  • JavaScript || 类和模块

    摘要:属性每个函数默认有属性方法返回的函数除外,其值为构造函数创建对象继承的对象。其思路使用原型链实现原型属性和方法的继承通过借用构造函数实现实例属性继承。 1 类和模块 每个独立的JavaScript对象都是一个属性的集合,独立对象间没有任何关系 ES5中的类是基于原型继承实现的:如果两个对象从同一个原型对象继承属性,称两个对象为同一个类的实例。r instanceof Range.pr...

    CoorChice 评论0 收藏0
  • ECMA_OOP

    摘要:效果不同事物之间的属性即使属性名相同,相互也不会发生冲突。命名空间的特点相互独立,而不冲突。而函数执行后的返回值,就是当前类的实例在构造函数当中,类中函数中出现的指代当前类的一个实例,不同实例之间的方法和属性是不同的。 对象 对象数据类型的作用:把描述同一个事物(同一个对象)的属性和方法放在同一个内存空间下,起到了分组的作用。 效果:不同事物之间的属性即使属性名相同,相互也不会发生冲突...

    yacheng 评论0 收藏0

发表评论

0条评论

hedzr

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<