原型
<script type="text/javascript">
/*
var obj = {}
console.log(obj);
console.log(obj.__proto__);//Object {}
console.log(obj.__proto__.__proto__);//null
*/
function Foo(){};
var foo = new Foo();
console.log(foo.__proto__);//Object {}
console.log(Foo.prototype);//Object {}
console.log(foo.__proto__ === Foo.prototype);//true
/*foo.__proto__到底要指向谁了?你怎么不能指向Foo这个函数本身吧,虽然函数也是对象,这个有机会会详细讲。
但如何foo.__proto__指向Foo固然不合适,因为Foo是一个函数,有很多逻辑代码,foo作为一个对象,继承逻辑处理没有任何意义,它要继承的是“原型对象”的属性。
所以,每个函数会自动生成一个prototype对象,由这个函数new出来的对象的__proto__就指向这个函数的prototype。foo.__proto__ --> Foo.prototype*/
总结:
1. 每个对象中都有一个_proto_属性。
JS世界中没有类(模具)的概念,对象是从另一个对象(原型)衍生出来的,所以每个对象中会有一个_proto_属性指向它的原型对象。
2. 每个函数都有一个prototype属性。
“构造函数”为何叫构造函数,因为它要构造对象。那么根据上面第一条事实,构造出来的新对象的_proto_属性指向谁了?总不能指向构造函数自身,虽然它也是个对象,但你不希望新对象继承函数的属性与方法吧。所以,在每个构造函数都会有一个prototype属性,指向一个对象作为这个构造函数构造出来的新对象的原型。
3. 函数也是对象。
每个函数都有一些通用的属性和方法,比如apply()/call()等。但这些通用的方法是如何继承的呢?函数又是怎么创建出来的呢?试想想,一切皆对象,包括函数也是对象,而且是通过构造函数构造出来的对象。那么根据上面第二条事实,每个函数也会有_proto_指向它的构造函数的prototype。而这个构造函数的函数就是Function,JS中的所有函数都是由Function构造出来的。函数的通用属性与方法就存放在Function.prototype这个原型对象上。
</script>

/**
*
* @authors Your Name (you@example.org)
* @date 2016-11-18 18:03:18
* @version $Id$
*/
函数对象:
function f1(){};
var f2 = function(){};
var f3 = new Function('str','console.log(str)');
普通对象:
var o3 = new f1();
var o1 = {};
var o2 =new Object();
简单的说,凡是通过 new Function() 创建的对象都是函数对象,其他的都是普通对象。原型的作用就是继承。
原型链:
JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__的内置属性,用于指向创建它的函数对象的原型对象prototype。
原型对象prototype中都有个预定义的constructor属性,用来引用它的函数对象。
person.prototype.constructor === person //true
Function.prototype.constructor === Function //true
Object.prototype.constructor === Object //true
总结一下:
var animal = function(){};
var dog = function(){};
animal.price = 2000;//
dog.prototype = animal;
var tidy = new dog();
console.log(dog.price) //undefined
console.log(tidy.price) // 2000
事实证明,真正起作用的不是prototype ,而是__proto__。
浙公网安备 33010602011771号