js中一切皆为对象(object),但是js中并没有类(class),js是基于原型(prototype-based)来实现面向对象(oop)的编程范式的,但并不是所有的对象都有原型(prototype)这一属性的。
例如:
var a={};console.log(a.protptype);//undefined
var b=function(){};console.log(b.prototype);//{}
var c='hello',console.log(c.prototype);//undefined
由此可以看出,prototype是每个function定义时自带的属性,但是,js中的function本身也是对象。
现在先看一下function,Function,Object和{}的区别
function是js的一个关键词,用于定义函数类型的变量,有两种语法形式:
function f1(){
console.log('This is function f1!');
}
typeof(f1); //=> 'function'
var f2 = function(){
console.log('This is function f2!');
}
typeof(f2); //=> 'function'
如果想用更加面向对象的方法来定义函数,可以用Function:
var f3 = new Function("console.log('This is function f3!');");
f3(); //=> 'This is function f3!'
typeof(f3); //=> 'function'
typeof(Function); //=> 'function'
由此可以看出,Function实际上是一个用于构造函数类型变量的类,或者说是函数类型实例的构造函数(constructor),和Object,String,Number类似,都是js内置类型实例的构造函数,但是Object比较特殊 ,它用于生成对象类型,其简写形式为{}
var o1 = new Object();
typeof(o1); //=> 'object'
var o2 = {};
typeof(o2); //=> 'object'
typeof(Object); //=> 'function'
prototype
VS __proto__
prototype和length是每一个函数类型自带的两个属性,其他非函数类型没有这两个属性,但是由于所有类型的构造函数本身也是函数,所以他们自带了prototype属性
// Node
console.log(Object.prototype); //=> {}
console.log(Function.prototype);//=> [Function: Empty]
console.log(String.prototype); //=> [String: '']
除了prototype属性外,js中所有对象(undefined,null等特殊情况除外),都有内置的[[prototype]]属性,这个属性指向他“父类”的prototype,这个内置属性在ECMA中没有给出明确的获取方式,但是许多js的实现都提供了一个_proto_属性来指代[[prototype]] ,可以通过下面的例子来说明实例中的_proto_是如何指向构造函数的prototype:
var Person=function(){};
Person.prototype.type='person';
Person.prototype.maxAge=100;
var p=new Person();
console.log(p.maxAge);
p.name='rainy';
Person.prototype.constructor===Person;//true
p._proto_===Person.prototype;//true
console.log(p.prototype);//undefined