JavaScript基础学习——ES6基础-类和模块

一、类

1、认识类(class)

类是对象的一个抽象,是对象的一个模板。对象是类的实例化。
    
定义:
      class 类名 {
        contructor(paramsList){ // 创建构造器
          this.x = x
          ...
        }
        // handle
      }

注意:
(1)类名一般首字母大写,用来跟普通函数进行区别。
(2)类不能直接调用,必须进行实例化处理。
(3)类的类型是function。
(4)类本身就指向构造函数。
(5)类不存在变量位置提升。
let p1 = new Person() // 会报错!实例化对象的代码必须写在类定义之后
class Person(){}
(6)类中的this指向的是当前实例化的对象的。

实例化:类在ES5中就是一个构造函数,可以通过new关键字进行实例化。var 实例化对象 = new 类名(实参列表);

class Person {
  constructor(name, sex, age, addr) {
    this.id = Math.ceil(Math.random() * 1000).toString();
    this.name = name;
    this.sex = sex;
    this.age = age;
    this.addr = addr
  }

  info() {
    return this.name + ":" + this.addr
  }
}

let p1 = new Person('zs', '男', 25, 'china')
let p2 = new Person('ls', '女', 22, 'china')

console.log(p1.name);
console.log(p1.info());
console.log(p2.info());

console.log(typeof Person);//function
console.log(Person === Person.prototype.constructor);//true

2、constructor():构造器

当实例化一个类时,它默认执行这个方法(也即是不需要单独去调用它)。

每个类有且只能有一个constructor方法,如果没有定义,类会自动添加一个constructor,内容为空。

作用:用来初始化数据,或将传进来的数据挂到实例化对象上。

class Animal1 {
  eat() {
    console.log("eat()");
  }
}

let cow1 = new Animal1()
console.log(cow1);

class Animal2 {
  constructor(name, type) {
    this.name = name;
    this.type = type
    var otherName = name;// 这里初始化变量,在外面获取不到,只能在当前范围内使用
  }

  eat() {
    console.log(this.name + this.type);
  }
}

let cow2=new Animal2('奶牛','草')
console.log(cow2);
console.log(cow2.otherName);//undefined

3、class表达式

const Person = class Human{};
const Person = class {};
const person = new class {}();

const Person1=class Human{}
const Person2=class{}
const person=new class{}()

console.log(Person1,Person2,person);
console.log(new Person1());
console.log(new Person2());
console.log(person);

4、class中的getter(取值)和setter(存储值)函数

getter与setter成对出现。

注意:当在类中出现getter和setter时,这时这个属性的值就取不到了,会自动产生一个以_开头的属性

class Human{
  constructor(name,tel){
    this.name=name;
    this.tel=tel;
  }

  //getter取值
  get tel(){
    return this._tel
  }

  //setter存值
  set tel(tel){
    this._tel=tel
  }
}

let h1=new Human("zs",'11111111111')

// h1._tel='11111111111'// 会自动调用setter
h1.tel='11111111111'

console.log(h1.tel);// 会自动调用getter

5、class中的generator方法

generator是ES6新增的用来解决异步编程的方法,语法与传统函数不一样。generator就是一个状态机,封装了多个内部状态。执行generator函数会返回一个遍历器对象。

generator有两个特征:
(1)function关键字与函数名之间有一个*号;
(2)函数体内部使用yield(产出)表达式定义多个内部状态(用来提取遍历后的数据)

注意:凡是方法名前加*,就表明这是一个generator函数,就可以使用状态机yield。

class Person {
  constructor(...args) {// 这里的...将把传过来的参数解析成一个数组
    this.args = args
  }

  //如果方法名前加*,表明这是一个generator函数
  //Symbol.iterator是一个内置的Symbol方法,它的作用是用来设置遍历器
  *[Symbol.iterator](){
    for(let stu of this.args){
      yield stu
    }
  }
}

for(let v of new Person('zs','ls','ww')){
  console.log(v);
}

6、class中的静态方法

在ES6中静态属性声明还未列入规范,也就意味在ES6中不能用static去定义静态属性。(结论:在ES6中只有静态方法,没有静态属性)静态方法可以使用static定义。静态方法只能写在class中,constructor之外,也可通过类添加。

静态方法特征:
(1)它不属于实例化对象,不能通过实例化对象调用,它只属于类自身。
(2)它只能通过类调用,格式:类名.静态方法名(参数)。
(3)它可以跟类中的其它方法同名。

class Student {
  constructor() {

  }

  static study() {
    console.log("study");
  }
}

let s1 = new Student()
Student.study()

Student.sports = () => {
  console.log('sport');
}

Student.sports()

7、类的继承

类的继承就是让子类拥有父类所有属性和方法,实现资源共享。
class 子类名 extends 父类名 {
      constructor(fatherArgs, childArgs){
        super(fatherArgs);// super用于继承父类的属性
        ...
      }
    }

// 父类
class Animal {
  constructor(props) {
    this.name = props.name || 'Unknown';
  }

  eat() { // 父类共有的方法
    console.log(this.name + '喜欢吃东西。');
  }
}

// 子类(同时继承父类Animal)
class Bird extends Animal { // 子类可以继承父类所有属性的方法,同时也可以拥有自己的属性和方法
  constructor(props, myAttribute) { // props是继承过来的属性,而myAttribute是该子类自己的属性
    super(props); // 相当于获得父类的this指向(相当于ES5中的Animal.call(this)
    this.type = props.type || 'Unknown';
    this.attr = myAttribute;
  }

  fly() { // 子类私有的方法
    console.log(this.name + '能飞得很远!');
  }

  myAttr() { // 子类私有的方法
    console.log(this.type + '---' + this.attr);
  }
}

// 实例化
let myBird = new Bird({
  name: '小燕子',
  type: '卵生动物'
}, '鸟类');

myBird.eat();
myBird.fly();
myBird.myAttr();

8、Object.getPrototypeOf()

通常可以使用instanceof来判断一个对象是否属于某一个类的实例对象。

通过Object.getPrototypeOf()可以获得一个类的隐式原型,用来判断一个类是否继承了另一个类。

//instanceof 判断某个对象是否是某个类的实例
class Human {
  constructor() {

  }

  say() {
    console.log('hello');
  }
}

let man = new Human()

let obj = {}

console.log(obj instanceof Human);// false 说明obj不是Human的实例

console.log(man instanceof Human);// true

console.log(obj instanceof Object, man instanceof Object);// true true 说明所有的对象都是Object的实例


// Object.getPrototypeOf() 一个类是否继承了另一个类
class Person {
  constructor() {

  }
}

class Teacher extends Person {
  constructor() {
    super()
  }
}

class Student {
  constructor() {

  }
}

console.log(Object.getPrototypeOf(Teacher) === Person);// true 说明Teacher这个类继承了Person这个父类

console.log(Object.getPrototypeOf(Student) === Person); // false

9、super

super用于继承父类的属性和方法。

class Person{
  constructor(info){
    this.sno=info.sno;
    this.name=info.name
  }
  study(){
    return this.name+" study"
  }
}

class Student extends Person{
  constructor(info){
    super(info)//继承父类的所有属性
  }
  content(){
    console.log(super.study()+'web'); // 这里的super用来继承(调用)父类的方法
    console.log(this.study()+'web');
  }
}

let tom=new Student({son:'111111',name:'zs'})

tom.content()

二、模块化开发

模块化程序设计是指在进行程序设计时将一个大程序按照功能划分为若干小程序模块,每个小程序模块完成一个确定的功能,并在这些模块之间建立必要的联系,通过模块的互相协作完成整个功能的程序设计方法。模块,就是指一个独立功能的JS文件。

ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。

在ES5(在ES6中仍然沿用)可以使用的模块化规范有:

CommonJS - 用在后台(是后台的一套模块化规范,目前它的实行者是Node.js)。
AMD - 用在前端,规范是通过RequireJS实现的。
CMD - 用在前端,规范是通过SeaJS实现的。

注意:在进行大型项目开发时,必用到模块化开发。

import{PI,r,Area,str,obj} from './modules01'
console.log(r);
console.log(Area());

console.log(str);// undefined   因为模块中没有暴露str

console.log(obj.gNum*obj.gPrice);
export const PI = 3.14
export let r = 10
let str = "abc"
export var obj = {
  gName:"签字笔",
  gPrice: 23,
  gNum: 2999
};
export function Area() {
  return PI * Math.pow(r, 2)
}

1、模块化开发基本用法

(1)用export导出(暴露变量或方法)

// // 用法1:
// export var a = 10;
// export function result() {
//   return a * a;
// }

// // 用法2:
// var a = 11;
// function result() {
//   return a * a;
// }
//   export {a, result}

// // 用法3:
// var variantA = 12;
// function result() {
//   return variantA * variantA;
// }
//   export {variantA as a, result as rs}

// // 用法4:
// export default {
//   a: 122,
//   rs: function(num){
//     return num * num;
//   }
// }

// 用法5(推荐写法):
let a = 13;
let rs = function () {
  return a * a;
};

export default { // 一个模块export default只能出现一次
  a, rs
}


(2)用import导入

// 用法1(导入整个文件(模块))
import './modules02'

// 用法2(选择性地导入)
import { a } from './modules02'

// 用法3(导入通过export default导出的模块)
import api from './modules02'

// 用法4(模块的整体加载)
import * as api from "./modules02"
// 用法1:
// export var a = 10;
// export function result() {
//   return a * a;
// }

// 用法2:
// var a = 11;
// function result() {
//   return a * a;
// }
//  export {a, result}

// 用法3:
// var variantA = 12;
// function result() {
//   return variantA * variantA;
// }
//  export {variantA as a, result as rs}

// 用法4:
// export default {
//   a: 122,
//   rs: function(num){
//     return num * num;
//   }
// }

// 用法5(推荐写法):
let a = 13;
let rs = function () {
  return a * a;
};

export default { // 一个模块export default只能出现一次
  a, rs
}

2、export命令的用法
    用法1:
    export var a = 10;
    export function result() {
      return a * a;
    }

    用法2:
    var a = 11;
    function result() {
      return a * a;
    }
     export {a, result}

    用法3:
    var variantA = 12;
    function result() {
      return variantA * variantA;
    }
     export {variantA as a, result as rs}

    用法4:
    export default {
      a: 122,
      rs: function(num){
        return num * num;
      }
    }

    用法5(推荐写法):
    let a = 13;
    let rs = function(){
      return a * a;
    };

    export default { // 一个模块export default只能出现一次
      a, rs
    }

  2-3 import命令用法
    // 用法1(导入整个文件(模块))
    import './modules02'

    // 用法2(选择性地导入)
    import { a } from './modules02'

    // 用法3(导入通过export default导出的模块)
    import api from './modules02'

    // 用法4(模块的整体加载)
    import * as api from "./modules02"

三、严格模式
  ES6 的模块自动采用严格模式,不管你有没有在模块头部加上"use strict";。

  严格模式主要有以下限制:
    变量必须声明后再使用
    函数的参数不能有同名属性,否则报错
    不能使用with语句
    不能对只读属性赋值,否则报错
    不能使用前缀 0 表示八进制数,否则报错
    不能删除不可删除的属性,否则报错
    不能删除变量delete prop,会报错,只能删除属性delete global[prop]
    eval不会在它的外层作用域引入变量
    eval和arguments不能被重新赋值
    arguments不会自动反映函数参数的变化
    不能使用arguments.callee
    不能使用arguments.caller
    禁止this指向全局对象
    不能使用fn.caller和fn.arguments获取函数调用的堆栈
    增加了保留字(比如protected、static和interface)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值