原型链:有限的实例对象和原型之间组成有限链,就是用来实现共享属性和继承的
JavaScript 中,万物皆对象!但对象也是有区别的。分为普通对象和函数对象.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| var o1 = {}; var o2 =new Object(); var o3 = new f1();
function f1(){}; var f2 = function(){}; var f3 = new Function('str','console.log(str)');
console.log(typeof Object); //function console.log(typeof Function); //function
console.log(typeof f1); //function console.log(typeof f2); //function console.log(typeof f3); //function
console.log(typeof o1); //object console.log(typeof o2); //object console.log(typeof o3); //object
|
在上面的例子中 o1 o2 o3 为普通对象,f1 f2 f3 为函数对象。怎么区分,其实很简单,凡是通过 new Function() 创建的对象都是函数对象,其他的都是普通对象。f1,f2,归根结底都是通过 new Function()的方式进行创建的。Function Object 也都是通过 New Function()创建的。
在对o3这个对象开始有点疑惑,在使用new操作符来调用一个构造函数的时候,发生了什么呢
1 2 3 4
| var obj ={}; obj.__proto__ = CO.prototype; CO.call(obj); return obj;
|
所以o3是个普通对象.
1.每个对象都有 __proto__
属性,但只有函数对象才有 prototype 属性
2.原型对象,顾名思义,它就是一个普通对象(废话 = =!)。从现在开始你要牢牢记住原型对象就是 Person.prototype.
原型对象 === 构造函数.prototype
3.所有的原型对象都会自动获得一个 constructor
(构造函数)属性,这个属性(是一个指针)指向 prototype
属性所在的函数(Person)
Person.prototype.constructor == Person
4.简单的原型链
先有的Object.prototype
, Object.prototype
构造出Function.prototype
,然后Function.prototype
构造出Object
和Function
。Object.prototype
是鸡,Object
和Function
都是蛋。
Function
, Array
, Object
, 包括 function Foo(){}
她们都是function
,所以她们继承自(也就是__proto__
) Function.prototype
。
1 2 3 4 5 6 7 8
| var obj1 = new Object(); var obj2 = {}; ---- var arr1 = new Array(); var arr2 = []; --- var fun1 = function (){}; var fun2 = new Function ();
|
而 var foo = (new Foo)
,包括var a = {}
只是一个普通object,她们继承于他们的构造函数的prototype, foo. __proto__
is Foobar.prototype;a.__proto__
is Object.prototype 。
5 __proto__
JS 在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__
的内置属性,用于指向创建它的构造函数的原型对象。
对象person1
有一个 __proto__
属性,创建它的构造函数是 Person
,构造函数的原型对象是 Person.prototype
,所以:
1
| person1.__proto__ == Person.prototype
|
6 函数对象 (复习一下前面的知识点)
所有函数对象的__proto__
都指向Function.prototype,它是一个空函数(Empty function)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| Number.__proto__ === Function.prototype // true Number.constructor == Function //true
Boolean.__proto__ === Function.prototype // true Boolean.constructor == Function //true
String.__proto__ === Function.prototype // true String.constructor == Function //true
// 所有的构造器都来自于Function.prototype,甚至包括根构造器Object及Function自身 Object.__proto__ === Function.prototype // true Object.constructor == Function // true
// 所有的构造器都来自于Function.prototype,甚至包括根构造器Object及Function自身 Function.__proto__ === Function.prototype // true Function.constructor == Function //true
Array.__proto__ === Function.prototype // true Array.constructor == Function //true
RegExp.__proto__ === Function.prototype // true RegExp.constructor == Function //true
Error.__proto__ === Function.prototype // true Error.constructor == Function //true
Date.__proto__ === Function.prototype // true Date.constructor == Function //true
|
JavaScript中有内置(build-in)构造器/对象共计12个(ES5中新加了JSON),这里列举了可访问的8个构造器。剩下如Global
不能直接访问,Arguments
仅在函数调用时由JS引擎创建,Math
,JSON
是以对象形式存在的,无需new。它们的__proto__
是Object.prototype
。如下
1 2 3 4 5
| Math.__proto__ === Object.prototype // true Math.construrctor == Object // true
JSON.__proto__ === Object.prototype // true JSON.construrctor == Object //true
|
上面说的函数对象当然包括自定义的。如下
1 2 3 4 5 6
| // 函数声明 function Person() {} // 函数表达式 var Perosn = function() {} console.log(Person.__proto__ === Function.prototype) // true console.log(Man.__proto__ === Function.prototype) // true
|
说明:
所有的构造器都来自于 Function.prototype
,甚至包括根构造器Object
及Function
自身。所有构造器都继承了Function.prototype
的属性及方法。如length
、call
、apply
、bind
Function.prototype
也是唯一一个typeof XXX.prototype为 function
的prototype
。其它的构造器的prototype
都是一个对象.
1 2 3 4 5 6 7 8 9 10
| console.log(typeof Function.prototype) // function console.log(typeof Object.prototype) // object console.log(typeof Number.prototype) // object console.log(typeof Boolean.prototype) // object console.log(typeof String.prototype) // object console.log(typeof Array.prototype) // object console.log(typeof RegExp.prototype) // object console.log(typeof Error.prototype) // object console.log(typeof Date.prototype) // object console.log(typeof Object.prototype) // object
|