zoukankan      html  css  js  c++  java
  • js中OOP小指南

    js中OOP小指南

    在指南中,我将尝试解析以面向对象规范聚焦的es6的新特性。

    首先,

    什么是设计模式

    范例是某个事务的例子或模型,在某种情况下,按照一种模式创建了计算机程序。

    什么是面向对象

    显然你意识到这是一种设计模式,像已经存在的这个模式,我们还有许多其它的设计模式,比如函数式编程和反应式编程。

    这种模式的特点

    我们在这个模式中所做的是以更接近实际的方式编程,我们使用类,对象,方法,属性等进行编程,并且集成了抽象,封装,模块化,隐私,多态和继承等术语。

    javascript的问题是,它不是一个很规范的语言,为什么?因为javascript所有的都是对象,因此我们可以使用很著名的prototype来解决这个问题。

    在ES5中,我们使用下面的例子实现工程模式:

    console.log('*** PERSON ***');
    function Person (name) {
     this.name = name;
    }
    // 明确属性和方法
    Person.prototype = {
       eyes: 2,
       mouth: 1,
       sleep: function () {
        return 'zzz';
       }
    };
    // 创建一个叫Nick的人
    const p1 = new Person('Nick');
    
    console.log(
      `name: ${p1.name}`,
      `eyes: ${p1.eyes}`,
      `mouth: ${p1.mouth}`,
       p1.sleep()
    );
    console.log('*** EMPLOYEE ***')
    // 如果我们有class属性,我们可以继承person的属性
    function Employee (name, salary) {
      this.name = name;
      this.salary = salary;
    }
    // Prototype 继承
    Employee.prototype = Object.create(Person.prototype);
    Employee.prototype.constructor = Employee; // Set his own constructor
    // 现在可以做相同的事情了
    // 创建一个employee
    const em1 = new Employee('John', 3000);
    
    console.log(
      `name: ${em1.name}`,
      `salary: ${em1.salary} USD`,
      `eyes: ${em1.eyes}`,
      `mouth: ${em1.mouth}`,
       em1.sleep()
    );
    

    现在使用ES6,用一种简单的方式实现上面的操作,但是一定记住这仅仅是语法糖:

    class Person {
      constructor (name) {
        this.name = name;
        this.eyes = 2;
        this.mouth = 1;
      }
      sleep () {
        return 'zzz';
      }
    }
    class Employee extends Person {
      constructor (name, salary) {
        super(name);
        this.salary = salary;
      }
    }
    const p1 = new Person('Nick');
    console.log(
      `name: ${p1.name}`,
      `eyes: ${p1.eyes}`,
      `mouth: ${p1.mouth}`,
       p1.sleep()
    );
    const em1 = new Employee('John', 3000);
    console.log(
      `name: ${em1.name}`,
      `salary: ${em1.salary} USD`,
      `eyes: ${em1.eyes}`,
      `mouth: ${em1.mouth}`,
       em1.sleep()
    );
    

    在这种情况下,通过extends关键字我们只需说:好吧,我想要继承Person类的属性。但在背后,这与我们在使用es5示例中的原型所做的相同。

    静态方法

    class Dog {
      static whatIs() {
       return 'A dog is a beatiful animal';
      }
    }
    // 因此,我们通过静态方法,不用实例化一个新的对象就可以访问方法
    console.log( Dog.whatIs() );
    

    私有属性

    javascript并不像java和C#那样拥有私有属性。重要的是,在JavaScript中我们有一个用于“私有”值的约定,该约定是在该单词之前使用下划线

    class Person {
     constructor (name, phone) { 
       this.name = name;
       this._phone = phone;
     }
    }
    const p1 = new Person('John', 544342212);
    // 实际上 'phone' 不是一个私有属性,因为我们可以这样使用:
    console.log(p1._phone);
    

    不过在ES6中,我们有一个叫WeakMap的对象,它允许我们创建私有属性。让我们来看下:

    // 因为它是保留字,所以不要使用private作为变量名称
    const secret = new WeakMap();
    class Person {
      constructor (name, phone) {
        this.name = name;
        secret.set(this, {_phonenumber: phone});
      }
    }
    const p1 = new Person('John', 544342212);
    // 现在_phonenumber是一个私有属性
    console.log(p1. _phonenumber); // Print's undefined
    

    Getters 和 Setters

    当我们拥有私有方法时通常会创建一个返回私有值的公共方法,因此我们必须返回一个值,并定义一个新的值。

    const secret = new WeakMap();
    class Person {
      constructor (name, phone) {
        this.name = name;
        secret.set(this, {_phonenumber: phone
      }
      get phoneNumber() {
        return secret.get(this)._phonenumber;
      }
      set phoneNumber(newNumber) {
        secret.get(this)._phonenumber = newNumber;
      }
    }
    const p1 = new Person('John', 544342212);
    const p2 = new Person('Tom', 111111);
    // 通过getter获取手机号
    console.log(p1.phoneNumber); // Print's the number
    // 设置新的手机号
    p1.phoneNumber = 432232323;
    p1.phoneNumber = 222222;
    console.log(p1.phoneNumber, p2.phoneNumber); // 获得新的手机号
    

    多态

    在执行过程中,一个对象引用它的类的事件或者任何子类的事件。子类可能会重新定义一种方法。

    class Person {
      constructor(name) {
        this.name = name;
      }
      me() {
        return `My name is ${this.name}`;
      }
    }
    const axel = new Person('Axel');
    console.log(axel.me());
      // ->  'My name is Axel'
    class Employee extends Person {
      constructor (name, salary) {
        super(name);
        this.salary = salary;
      }
      me() {
        return `My name is ${this.name} and my salary is ${this.salary}`;
      } 
    }
    const nick = new Employee('Nick', 3000);
    console.log(nick.me());
      // ->  'My name is Nick and my salary is 3000'
    

    一些概念

    • class:创建新的类或者模型。
    • constructor: 实例化类时初始化对象的方法。
    • extends: 用于设置继承
    • super: 设置调用父亲的继承属性的方法。supe必须位于构造函数的第一行。
    • get: 获取某个值的方法。
    • set: 重新定义某个值的方法。
  • 相关阅读:
    开发中的一些总结2
    XML与DataTable/DataSet互转(C#) 把数据库中表的内容转存为XML文件
    闲来无事。。。。
    一:Js的Url中传递中文参数乱码问题,重点:encodeURI编码,decodeURI解码:
    20120301 14:10 js函数内部实现休眠
    设为首页和收藏本站的代码
    Jquery实现对a标签改变选中的背景色 支持多选 再次点击背景色消失
    asp.net上传图片并生成等比例缩略图(.Net自带函数完成)
    类中只有 成员变量 和 一个成员函数表
    CListCtrl 使用技巧
  • 原文地址:https://www.cnblogs.com/open-wang/p/8970062.html
Copyright © 2011-2022 走看看