程序员人生 网站导航

JavaScript 中的"类"与"实例"

栏目:htmlcss时间:2015-01-24 08:53:27

JavaScript 中没有父类, 子类的概念, 也没有class 和 instance 的概念, 全靠 prototype chain来实现继承. 当查找1个对象的属性时, JavaScript 会向上遍历 prototype chain, 直到找到对应的属性为止. 有几种方法, 可使得 JavaScript 摹拟出 class 和 instance 的概念.

1, 直接使用构造函数来创建对象, 在构造函数内部使用 this指代对象实例.

> function Animal() { ... this.name = "animal"; ... } > Animal.prototype.makeSound = function() { ... console.log("animal sound"); ... } [Function] > var animal1 = new Animal(); > animal1.name; 'animal' > animal1.makeSound(); animal sound
再看另外1个例子:

> function Point(x, y) { ... this.x = x; ... this.y = y; ... } > Point.prototype = { ... method1: function() { console.log("method1"); }, ... method2: function() { console.log("method2"); }, ... } { method1: [Function], method2: [Function] } > var point1 = new Point(10, 20); > point1.method1(); method1 > point1.method2(); method2

以上, 先指定好1个构造函数对象的 prototype 属性. 然后 new 1个该对象实例, 便可调用 prototype 中指定的方法.

2, 使用 Object.create()方法来创建对象

> var Animal = { ... name: "animal", ... makeSound: function() { console.log("animal sound"); }, ... } > var animal2 = Object.create(Animal); > animal2.name; 'animal' > console.log(animal2.name); animal > animal2.makeSound(); animal sound
该方法, 比构造函数的方法更简便, 但不能实现私有属性和私有方法, 且实例对象之间不能同享数据, 对 class 的摹拟仍不够全面.
3, 荷兰程序员 Gabor de Mooij 提出的极简主义法(minimalist approach). 推荐用法.

> var Animal = { ... init: function() { ..... var animal = {}; ..... animal.name = "animal"; ..... animal.makeSound = function() { console.log("animal sound"); }; ..... return animal; ..... } ... }; > var animal3 = Animal.init(); > animal3.name; 'animal' > animal3.makeSound(); animal sound
不使用 prototype 和 this, 仅需要自定义1个构造函数init. 继承的实现也很简单.
> var Cat = { ... init: function() { ..... var cat = Animal.init(); ..... cat.name2 = "cat"; ..... cat.makeSound = function() { console.log("cat sound"); }; ..... cat.sleep = function() { console.log("cat sleep"); }; ..... return cat; ... } ... } > var cat = Cat.init(); > cat.name; // 'animal' > cat.name2; // 'cat' > cat.makeSound(); // 类似于方法的重载 cat sound > cat.sleep(); cat sleep

私有属性和私有方法的使用:

> var Animal = { ... init: function() { ..... var animal = {}; ..... var sound = "private animal sound"; // 私有属性 ..... animal.makeSound = function() { console.log(sound); }; ..... return animal; ..... } ... }; > var animal4 = Animal.init(); > Animal.sound; // undefined 私有属性只能通过对象本身的方法来读取. > animal.sound; // undefined 私有属性只能通过对象本身的方法来读取 > animal4.makeSound(); private animal sound
只要不是定义在animal对象上的属性和方法都是私有的, 外界不能访问.
类与实例之间, 可以做到数据同享.

> var Animal = { ... sound: "common animal sound", ... init: function() { ..... var animal = {}; ..... animal.commonSound = function() { console.log(Animal.sound); }; ..... animal.changeSound = function() { Animal.sound = "common animal sound changed"; }; ..... return animal; ..... } ... } > var animal5 = Animal.init(); > var animal6 = Animal.init(); > Animal.sound; // 可以视为类属性 'common animal sound' > animal5.sound; // 实例对象不能访问类属性 undefined > animal6.sound; undefined > animal5.commonSound(); common animal sound > animal6.commonSound(); common animal sound > animal5.changeSound(); // 修改类属性 undefined > Animal.sound; 'common animal sound' > animal5.commonSound(); common animal sound > animal6.commonSound(); common animal sound
如 Animal.sound 就是类与实例的共有属性, 可以视为类属性和类方法. 

若1个实例修改了该共有属性, 则该类和其他实例的共有属性也对应修改了.
综上, 就是 JavaScript 中摹拟的 class 和 instance 的概念和用法.



------分隔线----------------------------
------分隔线----------------------------

最新技术推荐