javascript中的原型链、面向对象的理解.

1.什么是原型链?

  在javascript中大部分东西都是对象,数组也是对象,函数也是对象,对象更是对象,不管是什么它们总有一些相同的方法和属性。

  当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的prototype的__proto__中查找,这样一层一层向上查找就会形成一个链式结构,我们称为原型链。

  原型链实现继承的主要方法是利用原型引用类型继承另一个引用类型的属性或者是方法。每一个构造函数都有一个原型对象(Person.prototype);原型对象都包含指向构造函数的指针(constructor);每个实例都包含指向原型对象的指针(看不见的_proto_指针)。某个构造函数的原型对象是另一个构造函数的实例;这个构造函数的原型对象就会有个(看不见的_proto_指针)指向另一个构造函数的原型对象;

  原型和原型链的概念中,prototype 就是原型,prototype 是函数特有的属性,普通的对象是没有 prototype 的,看下方例子:
    
var a = {}
var b; 
b = function () { }
function c() { }

console.log(a.prototype) // undefined,普通的对象是没有prototype,不是函数。 
console.log(b.prototype) // { constructor: ƒ }
console.log(c.prototype) // { constructor: ƒ }

  prototype 是让多个实例之间具有共享属性,看下面代码:

  

function num() {}
num.prototype.name = '张三' // 通过原型指向

var a = new num()
var b = new num()

console.log(a.name);  //继承了name属性
console.log(b.name);

  __proto__ 原理就是通过构造函数创建出来的实例中,该实例的内部具有一个 __proto__ 指针来指向构造函数的原型 prototype.

  实例和原型之间的关系则是实例的 __proto__ 指向了原型 prototype,即 __proto__ 和 prototype 指向了同一个内存空间.

  给大家看一个例子!   

<script>
  let data = 0;
  let c = 0
  // 第一个构造函数
  function SuperType() {
    data = 2;
  }
  SuperType.prototype.getSuperValue = function () {
    return data
  }

  //第二个构造函数;目前有一个属性
  function SubType() {
    c = 1
  }
  //继承了SuperType;SubType原型成了SuperType的实例;实际就是重写SubType的原型对象;给SuperType原型对象继承了
  SubType.prototype = new SuperType()

 //现在这个构造函数有两个属性(一个本身的subproperty,一个继承的存在原型对象的property);两个方法(一个原型对象的getSubValue,一个原型对象的原型对象的getSuperValue)
  SubType.prototype.getSubValue = function () {
    return c
  }
  var instance = new SubType() //创建第二个构造函数的实例

  // 会往上一级一级的
  console.log(instance.getSuperValue()) //2 先查找instance这个实例有没有此方法;显然没有,再查找SubType原型对象有没有此方法;也没有,再查找SubType原型对象的原型对象;显然是存在的
</script>
   注意:instance的constructor现在指向的是SuperType这个构造函数;因为原来的SubType.prototype被重写了,其内部的constructor也就随着SubType.prototype的原型对象的constructor指向构造函数SuperType;
    这说明一个对象所拥有的属性不仅仅是它本身拥有的属性,它还会从其他对象中继承一些属性。当js在一个对象中找不到需要的属性时,它会到这个对象的父对象上去找,以此类推,这就构成了对象的原型链.

2.面向对象:

  在javascript中面向对象是一种思想,万物皆是对象,程序中的模块都是可以看做对象,对象由属性和方法组成,面向对象会使用对象的属性和方法。

  说的通俗易懂一点就是把整个需求按照特点、功能划分开,将公共的部分封装成对象,下次要用的话可以直接拿来调用,创建对象不是为了完成某一个步骤,而是描述某个事物咋解决问题的步骤行为。

  举个例子吧,做一个下期的游戏:

  面向过程方式思考:(大概思维)

  1.红方下,

  2.实现红棋子运动的情况(判断运动方式)

  3.判断棋子是否吃掉对方的棋子(判断红方棋子是否能吃掉黑方棋子)

  4.黑方下,

  5.实现黑气棋子运动情况(判断运动方式)

  6.判断棋子施工吃掉对方棋子(判断黑方棋子是否能吃掉红方棋子)

  等等........

   循环,最后输出结果
  在上面的流程中发现有很多公共的部分,可以将他们封装通用,我们将繁琐的步骤,通过行为、功能,模块化,这就是面向对象.
  面向对象的三大特征是继承、封装、多态。JS可以模拟实现继承和封装,但是无法模拟实现多态,js是基于对象的语言,而非是面向对象的语言。
2.0.1面向对象的优缺点

  优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护
  缺点:性能比面向过程低

  低耦合,简单的理解就是说,模块与模块之间尽可能的独立,两者之间的关系尽可能简单,尽量使其独立的完成成一些子功能,这避免了牵一发而动全身的问题,为以后的维护和更改提供了方便。

 
posted @ 2019-08-15 17:14  迷茫_D  阅读(220)  评论(0编辑  收藏  举报