zoukankan      html  css  js  c++  java
  • Javascript面向对象编程

    https://segmentfault.com/a/1190000002900676

    介绍

    和java这种基于类(class-base)的面向对象的编程语言不同,javascript没有类这样的概念,但是javascript也是面向对象的语言,这种面向对象的方式成为 基于原型(prototype-base)的面向对象。虽然说ES6已经引入了类的概念来作为模板,通过关键字 “class” 可以定义类,但ES6的这种写法可以理解为一种语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。如果要理解基于原型实现面向对象的思想,那么理解javascript中得三个重要概念: 构造函数(constructor)、原型(prototype)、原型链(prototype chain) 对帮助理解基于原型的面向对象思想就显得尤为重要。下面就重点介绍一下这几个概念。

    javascript对象结构图

    先来看一张来自mollypages.org 的javascript对象的结构图,下面的例子都按照这张图阐述。

    构造函数(constructor)和原型 (prototype)

    构造函数是用来初始化对象的,每个构造函数都有一个不可枚举的属性,这就是原型(prototype).并且,每个prototype 都包含一个包含了不可枚举属性的constructor属性,这个属性始终会指向构造函数。

     function Foo(){};
     console.log(Foo.prototype.constructor === Foo); // true
    

    原型链(prototype chain)

    使用new实例化的原型

    每个被new实例化的对象都会包含一个__proto__ 属性,它是对构造函数 prototype 的引用。

      function Foo(){};
      var foo = new Foo();
      console.log(foo.__proto__ === Foo.prototype); // ture
    
      function Foo(){};
      console.log(Foo.prototype.__proto__ === Object.prototype); // true
    

    上面返回true 的原因是Foo.prototype 是Object预创建的一个对象,是Object创建的一个实例,所以,Foo.prototype.__proto_ 是Object.prototype的引用。

    我们可以来看一下原型链的脉络。

    函数(function)对象的原型

    在javascript中,函数是一种特殊的对象,所有的函数都是构造函数 Function 的实例。

      function Foo() {};
      console.log(Foo.__proto__ === Object.prototype); //false
      console.log(Fool.__proto__ === Function.prototype); // true
    
    

    从上面可以看出,函数Foo.__proto_ 指向到 Function.prototype, 说明函数 Foo 是 Function的一个实例。

     function Foo(){};
     console.log(Foo.__proto__ === Function.prototype); //true
     console.log(Foo.prototype.__proto__ === Object.prototype);//true
    

    Foo.prototype 是Object预定义的对象,构造函数为Object,所以__proto__指向 Object.prototype

    从上面的图我们可以看出, Object、Function、Array 等这些函数,他们的构造函数都是 Function 的实例。

    基于原型链的继承

    有了上面的基础知识以后,我们就可以自己去基于原型链去封装对象,实现javascript的继承。先来看下面一个例子。

    运行上面的例子,输入 cat init 和 animal eat,说明cat 继承了 Animal.prototype.eat 的方法。

    我们来分析一下代码。

    1、Animal 的prototype中定义了 eat方法。
    2、将Empty.prototype 指向 Animal.prototype , 所以 Empty.prototype 中也存在eat方法.
    3、Cat.prototype == new Empty(),所以 Cat.prototype.__proto_ === Animal.__proto_.
    4、重新为Cat指定constructor为Cat,否则Cat不存在constructor。

    这样就完成了继承,原型链是这样的:

    这样我们用原型链的方式实现了一个简单的继承方式。

  • 相关阅读:
    【SHOI2002】百事世界杯之旅
    【LGOJ 3384】树链剖分
    [20191006机房测试] 括号序列
    [20191006机房测试] 矿石
    【SHOI2012】回家的路
    [20191005机房测试] Seat
    [20191005机房测试] Silhouette
    每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样
    fgets函数读取最后一行的时候为什么会重复
    c语言中返回的变量地址,其物理地址在?(刨根问底)
  • 原文地址:https://www.cnblogs.com/xiaojikuaipao/p/5256041.html
Copyright © 2011-2022 走看看