【深入理解javascript】原型

1、一切都是对象

一切(引用类型)都是对象,对象是属性的集合

typeof函数输出的一共有几种类型,在此列出:

       function show(x) {

            console.log(typeof(x));    // undefined
            console.log(typeof(10));   // number
            console.log(typeof('abc')); // string
            console.log(typeof(true));  // boolean

            console.log(typeof(function () { }));  //function

            console.log(typeof([1, 'a', true]));  //object
            console.log(typeof ({ a: 10, b: 20 }));  //object
            console.log(typeof (null));  //object
            console.log(typeof (new Number(10)));  //object
        }
        show();
以上代码列出了typeof输出的集中类型标识,其中上面的四种(undefined, number, string, boolean)属于简单的值类型,不是对象。剩下的几种情况——函数、数组、对象、null、new Number(10)都是对象。他们都是引用类型。

判断一个变量是不是对象非常简单。值类型的类型判断用typeof,引用类型的类型判断用instanceof。

var fn = function () { };
console.log(fn instanceof Object);  // true

疑问:typeof的输出类型中,function和object都是对象,为何却要输出两种答案呢?都叫做object不行吗?

2、函数和对象的关系

对象都是通过函数创建的。

疑问:对象是函数创建的,而函数却又是一种对象——天哪!函数和对象到底是什么关系啊?

3、prototype原型

函数的prototype是一个属性,每一个函数都有这么一个属性,这个prototype的属性值是一个对象,这个对象默认只有一个constructor的属性,指向这个函数本身。对象是什么来,对象是属性的集合。

每个对象都有一个隐藏的属性——“__proto__”,这个属性引用了创建这个对象的函数的prototype

如以下代码,fn是一个实例对象,Fn是一个函数,则fn.__proto__ === Fn.prototype

 function Fn() { }
        Fn.prototype.name = '王福朋';
        Fn.prototype.getYear = function () {
            return 1988;
        };

        var fn = new Fn();
        console.log(fn.name);
        console.log(fn.getYear());

总结:每个函数function都有一个prototype,即原型。这里再加一句话——每个对象都有一个__proto__,可成为隐式原型。

4、隐式原型(这节重点记忆)

  • 每个对象的__proto__属性,指向创建该对象的函数的prototype。
var fn = new Foo();

fn._proto_ =  Foo.prototype //fn是由函数Foo创建的

 

  • 函数也不是从石头缝里蹦出来的,函数也是被创建出来的。谁创建了函数呢?——Function——注意这个大写的“F”

function Foo(){…}等价于var Foo = new Function(…),所以

Foo._proto_=Function.prototype //Foo是由函数Function创建的

//Object对象也是由函数Function创建的,Object=function Object(){[native code]}

Object._proto_ = Function.prototype

//Function对象也是由函数Function创建的,Function=function Function(){[native code]}

Function._proto_ = Function.prototype

//自定义函数Foo的prototype本质上就是和 var obj = {} 是一样的,都是被Object创建,所以:

Foo.prototype._proto_ = Object.prototype

//Function.prototype指向的对象也是一个普通的被Object创建的对象

Function.prototype._proto_ = Object.prototype

//Object.prototype确实一个特例——它的__proto__指向的是null,切记切记!

Object.prototype._proto_ = null

5、instanceof

Instanceof的判断队则是:沿着A的__proto__这条线来找,同时沿着B的prototype这条线来找,如果两条线能找到同一个引用,即同一个对象,那么就返回true。如果找到终点还未重合,则返回false

6、原型链

访问一个对象的属性时,先在基本属性中查找,如果没有,再沿着__proto__这条链向上找,这就是原型链。

posted on 2017-03-30 10:59  韩小亖  阅读(145)  评论(0编辑  收藏  举报

导航