ECMA2015(ES6)简单入门-4class基本语法

JavaScript中,生成实例的对象,通常通过构造函数,如下:

 function Fn(x,y){
  	this.x = x
  	this.y = y
  }
  Fn.prototype.toString = function(){
  	renturn '('+this.x+','+this.y+')'
  }
  var p = new Fn(1, 2)

Es6中引入class概念,可以看做是一个语法糖
上面的代码用Es6来写

 class Fn{
 	constructor(x,y){
 		this.x = x
 		this.y = y
 	}
 	toString(){
 		return '('+this.x+''+this.y+')'
 	}
 }

这里有一个constructor方法
这个Es6的Fn类的构造方法 就相当于 Es5中的构造函数 Fn
原型链中的扩展发方法,也可以直接在 class里面写出

  calss Fn(){ }
  typeof Fn // function
  Fn === Fn.prototype.constructor // true

上述代码说明类的数据类型就是函数
类本身就是构造函数 也是对类使用new命令

class Animal(){
	bark(){}
}
let dog = new Animal()
dog.bark()
构造函数的prototype属性在Es6的类上面继续存在
事实上 类的所有方法都定义在类的prototype属性上面
class Point{
	constuctor(){}
	toString(){}
	toValue(){}
}

等同于:

Point.prototype = {
	constructor(){},
	toString(){},
	toValue(){}
}

此类实例的调用方法,实际就是在调用原型上的方法

class B{}
let b = new B();
b.constructor === B.prototype.constructor //true

b就是B的实例,它的consturctor方法就是B类constructor方法
由于类的方法都定义在prototype对象上面,所以类的新方法,可以添加在prototype上面
Object.assign方法可以很方便的一次向类添加多个方法

class Point {
	constructor(){}
	Object.assign(Point.prototype,{
		toString(),
		toValue()
	})
}

另外类的所有定义发方法都是不可枚举的
但是Es5中方法可枚举

var Point = function (x, y) {
  // ...
};

Point.prototype.toString = function() {
  // ...
};

Object.keys(Point.prototype)
// ["toString"]
Object.getOwnPropertyNames(Point.prototype)
// ["constructor","toString"]

至于constructor方法是类的默认方法,通过new命令生成实例对象时,自动调用该方法
一个类必须要有constructor方法,如果没有显示定义,一个空的constructor方法会被默认添加
sonstructor方法默认返回实例对象,完全可以指定返回另外一个对象,

class Foo{
	constructor(){
		return Object.Create(null)
	}
}

new.Foo() instanceof Foo //false

生成类的实例的写法

class Foo {
  constructor() {
    return Object.create(null);
  }
}

Foo()
// TypeError: Class constructor Foo cannot be invoked without 'new'

与Es5完全一样,也是使用new命令,如果忘记加new 像函数那样调用class会报错,实例的属性除非显示定义在其本身,否则都是定义在原型上

class Point{
constructor(x,y){
this.x = x
this.y = y
}
toString(){
    return '(' + this.x + ', ' + this.y + ')';
}
let point = new Point(2,3)
point.toString()
point.hasOwnProperty('x')
point.hasOwnProperty('toString')
point.__proto__.hasOwnProperty('toString')
}

与Es5一样,类的所有实例共享一个原型对象。

var p1 = new Point(2,3)
var p2 = new Point(3,2)
p1._proto__  === p2.__proto__

我们可以用object.prototypeof方法来获取实例对象的原型然后来为原型添加方法
取值和存值
取值函数(getter)和存值函数(setter)

class MyClass {
	constructor(){
	}
	get prop(){
	return 'getter'
	}
	set pro(value){
	console.log(value)
}
}
let inst = new MyClass()
inst.props = 123
console.log(inst.prop)

上面代码中,prop属性有对应的存值和取值函数


属性表达式 类的属性名,可以采用表达式
 let methodName = 'getArea'
    class square {
    constructor(length){
    }
    [methodName](){
    }
    }

class表达式
类名,也可以用表达式

const myClass = class Me{
getClassName(){
return Me.name
}
}

采用表达式,可以写出立即执行的class
重点关注
类和模块内部默认是严格末世,不需要使用 use strict指定运行模式

不存在提升

name 属性

由于本质上,ES6 的类只是 ES5 的构造函数的一层包装,所以函数的许多特性都被Class继承,包括name属性。

class Point {}
Point.name // "Point"

name属性总是返回紧跟在class关键字后面的类名。

(4)Generator 方法

如果某个方法之前加上星号(*),就表示该方法是一个 Generator 函数。

    class Foo {
      constructor(...args) {
        this.args = args;
      }
      * [Symbol.iterator]() {
        for (let arg of this.args) {
          yield arg;
        }
      }
    }
    for (let x of new Foo('hello', 'world')) {
      console.log(x);
    }
// hello
// world

上面代码中,Foo类的Symbol.iterator方法前有一个星号,表示该方法是一个 Generator 函数。Symbol.iterator方法返回一个Foo类的默认遍历器,for…of循环会自动调用这个遍历器。

this 的指向

类的方法内部如果含有this,它默认指向类的实例。
解决办法
构造函数中绑定this
构造方法使用箭头函数

class Logger {
  constructor() {
    this.printName = this.printName.bind(this);
  }
  // ...
}
另一种解决方法是使用箭头函数。

class Obj {
  constructor() {
    this.getThis = () => this;
  }
}

const myObj = new Obj();
myObj.getThis() === myObj // true

静态方法 § ⇧ 类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
class Foo {
  static classMethod() {
    return 'hello';
  }
}
Foo.classMethod() // 'hello'
var foo = new Foo();
foo.classMethod()
// TypeError: foo.classMethod is not a function
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值