我们先理解原型之前,先来看看prototype和__proto__的区别;
1、prototype是函数Function才有的属性;
2、JS中每个对象都有一个__proto__属性;
例:
var a = {};
console.log(a.prototype); //undefined
console.log(a.__proto__); //Object {}
var b = function(){}
console.log(b.prototype); //b {}
console.log(b.__proto__); //function() {}
__proto__指向了谁
__proto__的指向取决于对象创建时的实现方式,看下面3个例子;
var a = {};
console.log(a.__proto__ == Object.prototype); //true
function P(){}; var b = new P();
console.log(b.__proto__ == P.prototype); //true
console.log(b instanceof P); //true
var obj1 = {}
var obj2 = Object.create(obj1)
console.log(obj2.__proto__ == obj1) //true
看一个有意思的现象
Function instanceof Object; //true
Object instanceof Function; //true
我们知道instanceof是检测一个对象是否是另一个对象new出来的实例
(例:var a = new Object(); a instanceof Object 返回 true)
我们来把他翻译成人类可以看懂的语音
//假设instanceof运算符左边是L,右边是R
L instanceof R
//instanceof运算时,通过判断L的原型链上是否存在R.prototype
L.__proto__.__proto__ ..... === R.prototype ?
//如果存在返回true 否则返回false
注意:instanceof运算时会递归查找L的原型链,即L.proto.proto.proto.proto…直到找到了或者找到顶层为止。
看到这有些不理解了,这些直接有什么联系吗?
答案是肯定的,千丝万缕啊。
原型链
我们例一个基础例子;
function Parent(){}
var child = new Parent()
我们把这个代码的整个原型链用图画出来就是这样的;
然后得到的结果是这样的
console.log(child.__proto__ == Parent.prototype) //true
console.log(child.__proto__.constructor == Parent) //true
console.log(Parent.prototype.constructor == Parent) // true
console.log(Parent.__proto__ == Function.prototype) //true
console.log(Parent.__proto__.constructor == Function) //true
console.log(Parent.__proto__.__proto__ === Object.prototype) //true
console.log(child.__proto__.__proto__ == Function.__proto__.__proto__) //true
console.log(child.__proto__.__proto__ == Object.prototype) //true
console.log(child.__proto__.__proto__.__proto__) //null
console.log(Function.__proto__.constructor === Function) //true
console.log(Function.__proto__ === Function.prototype) //true
console.log(Function.__proto__ === Object.__proto__) //true
console.log(Object.__proto__ === Object.prototype;) //false
console.log(Function.__proto__.__proto__ == Object.prototype) //true
清楚了prototype与__proto__的概念与关系之后我们会对“Js中一切皆为对象”这句话有更加深刻的理解。
我们可以理解__proto__是所有对象都内置的属性,而且指向父类的原型。