JavaScript入门——类(五)

类定义(ES6)

ES6 的类只是基于原型的语法糖;更易用。类支持基于原型的继承、调用父类、实例和静态方法,构造器。

class SkinnedMesh extends THREE.Mesh {
    constructor(geometry, materials) {
        super(geometry, materials)
        this.idMatrix = SkinnedMesh.defaultMatrix()
        this.bones = []
        this.boneMatrices = []
        //...
    }
    update(camera) {
        //...
        super.update()
    }
    static defaultMatrix() {
        return new THREE.Matrix4()
    }
}

ES6 之前

构造器函数

ES6 之前,JavaScript 没有类的概念,但有构造器的概念。构造器也是普通的函数,只是首字母一般大写,调用时加 new 关键字。

function Tester() { this.a = 1 }
var a = new Tester()
a instanceof Tester // true
console.log(a.a) // 1

构造产生的对象,可以显式返回或隐式返回。显式返回:

function Tester() {
    var a = 1
    return {good: a}
}
var a = new Tester()
a.good // 1

利用这种特性实现私有封装:

function Tester() {
    var age = 80
    return {
        getAge: function() { return age },
        setAge: function(v) { age = v }
    }
}
var a = new Tester()
a.getAge() // 80
a.age // undefined

隐式返回对象,即构造函数内不使用 return 语句,通过隐式变量 this 添加属性和方法。

function Tester() {
    this.good = 1
    console.log("done")
}
var a = new Tester()
a.good // 1

使用 new 构造的对象,构造函数即类:

function Tester() {
    this.good = 1
}
var a = new Tester()
a instanceof Tester // true

prototype 与方法

通过构造函数的 prototype 定义实例方法:

function Range(from, to) {
    this.from = from
    this.to = to
}

Range.prototype.includes = function(x) {
    return this.from <= x && x <= this.to
}

Range.prototype.foreach = function(f) {
    for(var x = Math.ceil(this.from) x <= this.to x++) f(x)
}

Range.prototype.toString =  function() {
    return "(" + this.from + "..." + this.to + ")" }
}

var r = new Range(1,3)
r.includes(2)
r.foreach(console.log)
console.log(r)

prototype 还有一个不可枚举的属性 constructor

var F = function() {}
var p = F.prototype
var c = p.constructor
c === F // => true: F.prototype.constructor==F for any function

类的实例也有 constructor 属性,也等于其构造函数。

var o = new F(); // Create an object o of class F
o.constructor === F // => true: the constructor property specifies the class

instanceof

两个对象继承自同一个原型对象时,它们是同一个类的实例。构造函数只是“类”的“外在表现”。例如下面的代码,instanceof 实际不会检查 r 是否是 Range 构造的。只是检查 r 是否继承自 Range.prototype

r instanceof Range // returns true if r inherits from Range.prototype

你可能感兴趣的:(JavaScript入门——类(五))