函数声明 1 2 3 var f1 = function ( ){}; function f2 = function ( ){}; var f3 = new Function ();
归根结底都是通过new Function 的方式来创建的,js中一切皆对象,对象又分函数对象和普通对象,简单来说通过new Function创建的就称之为函数对象,其他的都是普通对象
原型对象 在js中每一个对象(普通对象、函数对象)都有一个__proto__ 属性,函数对象都有一个prototype属性,指向函数的原型对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 var obj = {};var fn = function ( ){};console .log (obj.__proto__ ); console .log (obj.prototype ); console .log (fn.__proto__ ); console .log (fn.prototype ); var Animal = function ( ){ this .name = 'Tom' ; } Animal .prototype .say = function ( ){ console .log ('I am ' + this .name ) } var cat = new Animal ();var dog = new Animal ();cat.say (); dog.say ();
这里原型继承的问题,暂且按下不表(皮这一下,很开心~~)
原型链 上文说到,每一个对象都有一个__proto__ 属性,那么这个属性究竟有什么用呢?先来看几个例子
1 2 3 4 5 6 7 8 9 var Animal = function ( ){ this .name = 'Tom' ; } var cat = new Animal ();console .log (cat.__proto__ === Animal .prototype ); console .log (Animal .prototype .__proto__ === Object .prototype ); console .log (Object .prototype .__proto__ === null );
从这个例子中可以看出 __proto__ 属性指向构造函数的原型对象prototype,而prototype也是一个普通对象,也有__proto__属性,继续指向其构造函数,直到指向null,这样就形成了一个原型指向的链条,专业术语称之为原型链。 至于为什么最终是null,如果非要解释的话,引用道德经中的一句话:有,是万物之所始;无,是万物之所母。 此外,Function、Object作为js的内置函数对象,需要清楚一点,他们都是 new Function创建的
console.log(Function.constructor === Object.constructor); // true
new 的实现过程 通过new 一个构造函数得到一个对象,看一下内部实现过程,有助于帮助理解原型链指向
1. 声明一个对象 var obj = {};
2. obj.\_\_proto__ = 构造函数.prototype;
3. 改变this指针,通过call、apply让this指向第一步创建的obj;
4. 返回对象obj;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function Animal (name ){ this .name = name; } Animal .prototype .say = function ( ){ console .log ('I am ' + this .name ) } function myNew ( ) { var obj = {}; var Constructor = [].shift .call (arguments ); console .log (Constructor .prototype ); obj.__proto__ = Constructor .prototype ; Constructor .apply (obj,arguments ); return obj; } var cat= myNew (Animal ,'Tom' );console .log (cat.name ); cat.say (); console .log (cat.constructor );
大招 如果以上内容还是不太明白,我自己做了张注解图(线条有点多而杂,见谅~~),以及代码案例帮助理解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function Animal ( ){}var cat = new Animal ();cat.constructor == Animal ; cat.__proto__ === Animal .prototype ; Animal .constructor === Function ; Animal .prototype .__proto__ === Object .prototype ; Animal .__proto__ === Function .prototype ; Object .constructor === Function ; Object .__proto__ === Function .prototype ; Object .prototype .__proto__ === null ; Function .constructor === Function ; Function .__proto__ === Function .prototype ; Function .prototype .__proto__ === Object .prototype ;