我来重新学习 javascript 的面向对象(part 1)

我来从新学习 javascript 的面向对象(part 1)

许多job 的形貌都说请求通晓 javascript 面向对象编程,然则依据平常的套路,写通晓实在就是闇练,写闇练实在就是平常,写平常实在就是懵逼!

《我来重新学习 javascript 的面向对象(part 1)》

虽然话说云云,然则我们照样要闇练运用 javascript 面向对象编程的,毕竟这是js社会高能人材的个中一个规范,这里我就用一个新鲜的例子来申明和明白我们应当怎样运用javascript 面向对象的体式格局来编程。

一、蛮横体式格局构建对象

刚开始最初,我们建立对象的体式格局是如许的:

// 。。。。每次都要写上面的一大段代码,只是为了建立一个 food
var food = new Object();
food.name = "苹果";

food.sayName = function() {
  console.log("我是" + this.name);
};

然则如许建立起来很贫苦,写的代码也是很长,假如要建立很多对象,比方我制作了10000个食品,就要写10000次这一大段代码了,所以厥后伶俐的工程师改为了如许写:

// 最少比之前的少了几行,也整齐了一些
var food = {
  name: "苹果",
  sayName: function() {
    console.log("我是" + this.name);
  }
};

最少代码少了一些,然则照样没办法很好处理我要写100000段代码的题目,所以再厥后的人们就开始运用一些高等玩意来处理这个题目。

二、运用工场形式构建对象

经由历程笼统出建立详细对象的历程,用函数来举行封装,换句话来讲,就是笼统了一个 food 的工场,然后经由历程对这个工场传入差别的材料,来天生差别的食品。

function createFood(name) {
  var o = new Object();
  o.name = name;
  o.sayName = function() {
    console.log("我是" + this.name);
  };
  return o;
}

var food1 = createFood("苹果");
var food2 = createFood("苹果");

这里能够看到food1,food2 就是如许被制作出来的,然后只需要少许的代码(预先定义好一个临盆工场函数),就能够完成大批的事变,完整处理了题目,完成了多快好爽的新局面。然则用了一段时候以后,随之而来发明一个新题目,当食品多起来的时刻,老板貌似不知道哪些食品是属于那些分类的(假定老板是 zz),那怎样办呢?

// 都统一返回是[Function: Object],没办法用辨别辨认(卖个关子,你不必管谁人constructor)
console.log(food1.constructor) // 返回[Function: Object]
console.log(food2.constructor) // 返回[Function: Object]

三、运用组织函数形式来辨别自己人

经由一番伶俐交换以后,伶俐的人们想出了一个要领,运用一个在对象内里的 constructor 函数来辨认那些不一样的对象,相似运用部门工牌来标记这个人是是属于哪一个部门的。

function Food(name) {
  this.name = name;
  this.sayName = function() {
    console.log("我是" + this.name);
  };
}

var food1 = new Food("苹果");
var food2 = new Food("苹果");

// 假定这里有一个其他的食品,多是假装的
var food3 = new otherFood("苹果");

由于要完成相似工牌的体式格局来辨认,所以在建立food的工场里做一些调解:

  • 没有显式的建立对象,比方:var o = new Object();
  • 直接将属性和要领付给了 this 对象
  • 没有 return 语句
  • 函数运用了大写字母开首(这里只是为了辨别这个函数的迥殊,根据通例,大写字母开首的,平常都是 class 或许组织函数)
  • 运用了 new 来建立Food`对象

做了以上的转变以后,全部建立对象的形式被转变了:

  1. 起首定义了一个 Food 的组织函数(实在就是之前的工场函数createFood,然则如今晋级了)
  2. 经由历程 new 来建立一个对象(如今的 Food 用 new 来先建立)
  3. 将组织函数的作用域赋值给新对象,将this指向这个新对象(将晋级版的工场送给这个用 new 建立的 food)
  4. 实行组织函数的中的代码(晋级版的工场会自动将内里的零件和机械放到新的 Food 上,相当于组装放在了食品自身 身上)
  5. 不需要主动 return,自动返回新对象(晋级版的工场会自动返回组织好的 food 对象)

经由历程这类体式格局,我们制作出来的食品都邑有一个 constructor 为 Food 的标记来标识,假如看到不是的话,那一定就不是我们制作的。

console.log(food1.constructor) // 返回[Function: Food]
console.log(food2.constructor) // 返回[Function: Food]
console.log(food3.constructor) // 返回[Function: OtherFood]

// 磨练的体式格局有两种
console.log(food1.constructor == Food) // 返回 true
console.log(food2.constructor == Food) // 返回 true
console.log(food3.constructor == Food) // 返回 false ,这个不是我们制作的食品

console.log(food1 instanceof Food) // 返回 true
console.log(food3 instanceof Food) // 返回 false,这个不是我们制作的食品

能够看到,运用了新手艺(constructor形式手艺)以后,在没有增添工作量的情况下,处理了使人头痛的题目,简直是圆满,不过过了一段时候以后,发明彷佛照样有些瑕疵,运用组织函数constructor形式的时刻,函数内里的每一个要领都邑在每一个实例上从新建立一遍,那末最显著的处所是:

console.log(food1.sayName == food2.sayName); // 返回 false

由于运用new来建立实例,new的话还会把组织函数内里的要领也一同建立,由于要领也是函数,而函数的实例化也会被new触发:

// 省略了其他部份,只关注要领部份
this.sayName = function() {
    console.log("我是" + this.name);
};

this.sayName = new function() {
    console.log("我是" + this.name);
}();

如许就会形成内存和时候和机能的糟蹋,明显不需要从新重修新的函数实例的。

实在在之前的工场形式内里,也存在这个题目,不过工场形式更完整,直接完整建立一个新对象,而组织函数形式的话只是要领会被从新建立。

那怎样处理呢?会用到原型形式,下回分解。

参考内容

  1. 红宝书,《javascript 高等程序设计第三版》

版权信息

作者: 怂如鼠

网站:
https://www.whynotbetter.com

本作品著作权归作者一切,贸易转载请联络作者取得受权,非贸易转载请说明出处。

    原文作者:线上猛如虎
    原文地址: https://segmentfault.com/a/1190000016114593
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞