写在前面
这篇文章我的目的是试图讲清楚prototype与__proto__。很多人也许和我一样,很困扰于这两个东西究竟是干啥的,网上的各种资料也是讲的云里雾里,傻傻分不清楚。今天我就来尝试把它们说清楚。
JavaScript里没有类的概念
首先必须明确这一点,如果你学过Java之类的面向对象语言,你肯定熟悉类的概念,在面向对象语言的逻辑里,我们要先设计类(Class),然后再把类实例化成对象(Object),就像是图纸和产品的关系,我们必须先设计“图纸”,然后才能打造“产品”。
而在JavaScript里,根本没有类的概念,它的所有东西都是对象,其实,这并没有什么问题,不是所有语言都必须像Java一样必须依赖类这个概念设计,比如C语言里也没有类的概念,一样活得很好。不过,我们必须承认,类的思想会给工程问题带来很多方便,所以,在JavaScript的不断发展中,一些需求也催生了JavaScript想模仿类这个概念。比如说,如果你想构建一个有一定规模的项目,那你必然会涉及到一些继承问题,而这种继承问题,在Java中就是用类来解决的,那在JavaScript中,我们该怎么办?当然有办法,那就是模仿,我们没有类,但我们可以模仿类,而且随着时代的发展,我们有了更好的方法。prototype与__proto__都是在这个过程中催生的产物,我们一会儿马上讨论,在这之前,我们先明确一下类型(type)的概念。
我们没有类(Class),但我们有类型(Type)
上面说过,JavaScript没有类的概念,它里面的所有东西都是对象,但他的对象是有类型的,英文是type。
关于类型的总结,基本上每本教科书上都会列举的很清楚,分两种,原始类型(Primitive Types)与引用类型(Reference Types)。
原始类型(5种):Boolean、Number、String、Null、Underfined
引用类型(6种):Array、Date、Error、Function、Object、RegExp (其实也不止这些)
在javascript中,可以用typeof
操作符判断一个变量的类型,关于typeof
也要说明一点,5中原始类型都可以用它判断出来(除了Null,Null类型返回object),但对于引用类型,只有两种返回值:function和object,这也就说明了一点,其实引用类型根本上只有两种,那就是Function和Object,其他的引用类型都是Object衍生出来的(它们都返回Object),下面代码可以验证:
//代码1
var boo = true;
var num = 123;
var str = "hello world!"
var nu = null;
var und;
var fun = new Function();
var arr = new Array();
var dat = new Date();
var err = new Error();
var obj = new