Java程序员眼中的Javascript面向对象

Javascript面向对象

为什么是Java程序员?因为面向对象的概念一般喜欢用Java来讲,懂面向对象的人一般都懂Java。按照从已知到未知的原则,我给Javascript的面向对象找个方便类比的东东。

1. 猫的构造函数

首字母大写的一个函数,可以通过参数来设置属性(properties)。如下:

function Cat(type) {
    this.type = type;
}

一个对象,可以用new来创建:

var whiteCat = new Cat('white'); 
console.log(whiteCat instanceof Cat);  //输出:true

看样子,Cat很像Java的类。但在Javascript里面,没有类的概念,这只是一个构造函数(Constructor)。对象whiteCat是构造函数Cat的一个instance。

console.log(typeof Cat);  //输出:function
console.log(typeof whiteCat);  //输出:object

2. 小白猫的原型是白猫

Javascript对象,可以有一个原型(prototype)对象。自己没有定义的方法,如果原型对象有定义,也可以直接调用。哈哈,这就像是Java里面的类继承的概念,只不过,Javascript里面没有类,主体是对象。

用如下Object.create方法可以把一个对象whiteCat设置成另一个对象littleWhiteCat的原型:

var littleWhiteCat = Object.create(whiteCat);
whiteCat.say = function() {
    console.log("maomao");
}
whiteCat.say();   //输出:maomao
littleWhiteCat.say();   //输出:maomao

可以用如下Object.getPrototypeOf方法查看一个对象的原型对象:

console.log(Object.getPrototypeOf(littleWhiteCat) == whiteCat);  //输出:true

3. 白猫的原型是什么?

前两个概念都比较简单,两个合在一起对于Java程序员来说就有点绕了。

小白猫对象littleWhiteCat的原型对象是白猫whiteCat,白猫是用构造函数Cat创建的,那么白猫的原型对象是什么?

白猫的原型对象不是Cat,因为Cat只是个构造函数而已,白猫的原型对象是Cat.prototype

console.log(Object.getPrototypeOf(whiteCat) == Cat.prototype);  //输出:true

可以把Cat.prototype看成一个整体,Javascript里面,每个构造函数X都有一个X.prototype的对象,作为用new X创建对象的原型对象。

4. 让猫吃东西

按照前面讲的原型对象的“继承”关系由下向上线条是:

littleWhiteCat ——> whiteCat ——> Cat.prototype

所以,如果想给猫增加个吃东西的方法,只需要对Cat.prototype下手即可:

Cat.prototype.eat = function() {
    console.log(this.type, ': Cat eat fish!');
}
console.log(whiteCat.eat());  //输出:white : Cat eat fish!
console.log(littleWhiteCat.eat());  //输出:white : Cat eat fish!

如果小白猫喜欢吃老鼠,类似Java中方法重载的概念:

littleWhiteCat.eat = function() {
    console.log('littleWhiteCat eat mouse!');
}
console.log(whiteCat.eat());  //输出:white : Cat eat fish!
console.log(littleWhiteCat.eat());  //输出:littleWhiteCat eat mouse!

5. 机器猫的构造函数

前面讲的白猫whiteCat是一个对象,“继承”自Cat.prototype。如果有一类猫是机器猫,机器猫里有好多只,最有名的是哆啦A梦,哈哈。

创建一个机器猫MachineCat的构造函数,调用Cat的构造函数。哆啦A梦dola就用机器猫的构造函数来创建。

function MachineCat(type) {
    this.pocket = 'a lot of good things.';
    Cat.call(this, type);
}
var dola = new MachineCat('blue');  

以上代码,机器猫MachineCat和猫Cat并没有什么关系,哆啦A梦不能称之为猫,也不能调用猫的一些方法,比如eat()。给他们建立联系,需要如下一个关键操作:

MachineCat.prototype = Object.create(Cat.prototype);

这时,哆啦A梦,不但是机器猫的instance,而且是猫的instance了。这太像Java的类继承了。

var dola = new MachineCat('blue');  // dola需要在机器猫和猫的关系确定后,重新创建
console.log(dola instanceof MachineCat);  //输出:true
console.log(dola instanceof Cat);  //输出:true
dola.eat();     //输出:blue : Cat eat fish!

这时,“继承”关系由下向上的链条是:

dola ——> MachineCat.prototype ——> Cat.prototype

console.log(Object.getPrototypeOf(dola) == MachineCat.prototype);  //输出:true
console.log(Object.getPrototypeOf(MachineCat.prototype) == Cat.prototype);  //输出:true

6. 一些奇怪东西的分析

在Javascript里面,一切都是对象。函数本质也是个对象,所以,这个很像Java类的构造函数Cat,本质也是个对象。那这个对象的原型对象是什么呢?

console.log(Object.getPrototypeOf(Cat) == Function.prototype);  //输出:true

类似的,数组,字符串,数字等等,也是对象,也有原型对象:

console.log(Object.getPrototypeOf([1,2,3]) == Array.prototype);  //输出:true
console.log(Object.getPrototypeOf(1) == Number.prototype);  //输出:true
console.log(Object.getPrototypeOf('abc') == String.prototype);  //输出:true

这些奇奇怪怪的xxx.prototype也是对象啊,他们的原型对象一般是:

console.log(Object.getPrototypeOf(Cat.prototype) == Object.prototype);  //输出:true
console.log(Object.getPrototypeOf(Function.prototype) == Object.prototype);  //输出:true
console.log(Object.getPrototypeOf(Array.prototype) == Object.prototype);  //输出:true
console.log(Object.getPrototypeOf(Number.prototype) == Object.prototype);  //输出:true
console.log(Object.getPrototypeOf(String.prototype) == Object.prototype);  //输出:true

这些貌似Java类的Array等东东,其实都是Javascript里面原生的构造函数:

console.log(typeof Function == 'function');  //输出:true
console.log(typeof Array == 'function');  //输出:true
console.log(typeof Number == 'function');  //输出:true
console.log(typeof String == 'function');  //输出:true
console.log(typeof Object == 'function');  //输出:true

以上,就是Javascript的面向对象概念的素描。没有类的Javascript是不是更好玩呢?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容