刚接触js原型的时候比较迷惑,对象跟原型到底是怎么回事,函数跟对象和原型是什么关系,原型个隐式原型到底是什么这些问题,一头雾水,现在算是有了一些头绪,希望借助上面的图以及部分演示代码能把他们的关系说明白;
核心观点:图中两个节点Function的原型 Function.prototype和Object的原型 Object.prototype,非常特殊,因为js重所有的构造函数最终会指向Function.prototype, 所有的原型最终都会指向Object.prototype
为了最快速度说明白这张图,就不做铺垫了,按照上结论+示例+简单解释的模式叙述
- js里一切都是对象,函数也是对象,你可以为对象设置任何你想要的属性,所有对象均由函数创建,每个函数都自带一个prototype属性,指向一个对象(这里称作prototype),函数通过prototype属性访问这个对象,与之对应prototype对象通过constructor访问函数
上代码:
function f(){}
f instanceof Object//true 引用类型判断类型用instanceof
给f添加name属性
f.name= "我是函数f";//通过 f.name 是可以得到这个字符串的,这里
name可以是字符串,数字,数组,对象,都可以的;
为什么要举例f.name呢, 是为了类比f.prototype ,prototype就跟name一样, 是函数自带的一个属性,它是一个对象, 在chrome浏览器中输入f.prototype 会返回一个对象,点开后会发现它有一个属性叫做constructor, 没错, prototype是对象, 它也可以有属性,它的constructor属性指向函数f,所以图中的prototype和constructor两条线就可以理解了;
这里验证双方的指向关系
f.prototype.constructor === f//true, 可以理解为相互指定
2 对象由函数创建,此时我们称这个函数为构造函数,被构造函数创建的对象称为构造函数的一个实例, 有点绕,简单讲就是构造函数和实例的关系,新创建的对象有一个属性 _ _ proto _ _ 指向构造函数的原型对象,这里提示一下,实例并不指向构造函数,而是指向构造函数的原型对象,如果想通过实例找到构造函数,可以先通过 _ _ proto _ _ 找到构造函数的原型对象,然后通过constructor找到构造函数(这里不说原型链,直接通过constructor寻找构造函数了,所以就先这么理解)
var fObj = new f();
fObj.__proto__.constructor === f;//true
3.函数也是对象,所有函数也由函数创建,所有的函数都是由构造器Function创建的, 纳尼?你是在逗我么?不是的啊, Array, String, Boolean都是函数,先验证一下了,看代码:
Array
//function Array() { [native code] }
Boolean
//function Boolean() { [native code] }
String
//function String() { [native code] }
全是function的
上面说了,对象都是由函数创建的,一切皆对象,函数也是对象,函数当然也是被函数创建的了,用我们最新学的prototype验证吧
Array.__proto__.constructor === Function//返回true的!
到了这里你可能会问了, 那Function是谁创建的呢?或者它的隐式原型是谁呢?它的原型以及隐式原型共同指向Function.prototype
比较奇怪,难不成是自己创建自己?是的啊,看代码:
Function.__proto__ === Function.prototype//true
4.函数的原型是对象, 那它是谁创建的呢?没错, 你可能已经猜到了,是由函数Object创建的, 那,现在考考你Object是谁创建的呢?
不用等了, 现在就告诉你答案,Object是对象的构造函数,函数由函数创建,所以它是被Function创建的啦
Object.__proto__.constructor === Function//true
到了这里还有最后一问:Object的原型—Object.prototype是被谁创建的呢?难不成它还自己创建自己么?不是的啦,它的隐式原型 _ _ proto _ _指向为空
差不多就是这样了;
配合上面的图,结合下面的文字,相信对原型,函数,隐式原型( _ proto_ )会有一些概念的
希望对看到的同学有帮助;
水平有限,难免错误(肯定会有的,后续会不断更正)