顺手官网
JavaScript 对象是动态的属性“包”(指其自己的属性)。JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。
整篇文章写完之后,发现内容太多。总节以下几点。详情爱看不看23333333
prototype
初始包含:constructor
和 __proto__
__proto__
用于指向创建它的那个构造函数的prototype
constructor
属性,指向创建它的构造函数Object.prototype.__proto__
指向null
表示原型链到头了普通函数
与构造函数
"new Symbol()"
Function
创建的,因此:constructor
都指向Function
,连Object
和Function
自己也不例外__proto__
都指向Function.prototype
,连Object
和Function
自己也不例外虽然网上有很多版本的关系图,但我还是自己画一个。
先说明一下一般的函数如 function MyMethod(){}; Array,Number,String...
这些都属于 Fn
级别。Function
和Object
两个构造器辈份太大属于特殊情况。
var fn = new Array(1,2,3,4);
console.info(fn.constructor === Array);// true
console.info(fn.__proto__ === Array.prototype);// true
var obj = {};
console.info(obj.constructor === Object);// true
console.info(obj.__proto__ === Object.prototype);// true
一个实例对象通过它的 __proto__
属性指向它爹的 prototype
属性。
// 这里我直接用内置对象 Array 其实用自己声明的函数也一样。 Array 虽然是数组类型,但它首先也是 Function 的一个实例
// Fn
console.info(Array.constructor === Function);// true
console.info(Array.__proto__ === Function.prototype);// true
console.info(Array.hasOwnProperty('prototype'));// true
// Function
console.info(Function.constructor === Function);// true Function的构造函数只能是它自己。构造函数的祖宗就在这了。
console.info(Function.__proto__ === Function.prototype);// true
console.info(Function.hasOwnProperty('prototype'));// true
// Object
console.info(Object.constructor === Function);// true
console.info(Object.__proto__ === Function.prototype);// true
console.info(Object.hasOwnProperty('prototype'));// true
// Fn.prototype
console.info(Array.prototype.constructor === Array);// true
console.info(Array.prototype.__proto__ === Object.prototype);// true
// Function.prototype
console.info(Function.prototype.constructor === Function);// true
console.info(Function.prototype.__proto__ === Object.prototype);// true
// Object.prototype
console.info(Object.prototype.constructor === Object);// true
console.info(Object.prototype.__proto__ === null);// true
__proto__
指向 爹.prototype
下面详细的聊聊
prototype
属性prototype
上.prototype.__proto__
指向谁的 .prototype
// 首字母大写潜规则。表示这个函数是想当构造函数用的。
function Test(){};
Test.prototype.hehe = function(){
console.info("呵呵!");
}
function Test2(){};
Test2.prototype = new Test();
// 创建实例
var test2 = new Test2();
test2.hehe();// 呵呵!
执行test2.hehe()
时,首先在test2
下找,肯定是没的。那么就它就继续顺藤__proto__
摸瓜Test.prototype
在Test.prototype
中找到了hehe
就执行,没找到就再往上,一直找到 Object.prototype
去。
prototype
属性(这是创建对象时由系统完成的)test2.__proto__
Object.getPrototypeOf(test2) === test2.__proto__; // true
test2.__proto__ === Test2.prototype;// true
可见所有函数都是由 Function 构造函数创建的。
console.info(Function.constructor === Function.prototype.constructor);// true
console.info(Object.constructor === Function.prototype.constructor);// true
console.info(Array.constructor === Function.prototype.constructor);// true
console.info(String.constructor === Function.prototype.constructor);// true
所有实例对象的constructor
指向创建它的构造函数。
function MyMethod(){};
var myfn = new MyMethod();
console.info(myfn.constructor === myfn.__proto__.constructor);// true
所有构造函数的.prototype.constructor
指向函数自己
function MyMethod(){};
console.info(MyMethod.prototype.constructor === MyMethod);// true
console.info(Array.prototype.constructor === Array);// true
console.info(String.prototype.constructor === String);// true
console.info(Function.prototype.constructor === Function);// true
console.info(Object.prototype.constructor === Object);// true
__proto__与Function.prototype
function MyMethod(){};
console.info(MyMethod.__proto__ === Function.prototype);// true
console.info(Array.__proto__ === Function.prototype);// true
console.info(String.__proto__ === Function.prototype);// true
console.info(Number.__proto__ === Function.prototype);// true
console.info(Set.__proto__ === Function.prototype);// true
// 不用我把所有js内置对象都列出来了吧。。。
据说Function.prototype
是一个特殊的匿名函数ƒ(){ [native code] }
此函数的__proto__
指向Object.prototype
。
又有人说 JavaScript
直接规定的 Function.prototype.__proto__ === Object.prototype
(反正结果一样)
Object.prototype.__proto__
指向 null
表明到达原型链末端。
// Function
Function.prototype;// ƒ () { [native code] }
Function.prototype.__proto__ === Object.prototype;// true
// Object
Object.prototype.__proto__ === null;// true
function MyMethod(){};
console.info(MyMethod.prototype.__proto__ === Object.prototype);// true
console.info(Array.prototype.__proto__ === Object.prototype);// true
console.info(String.prototype.__proto__ === Object.prototype);// true
console.info(Number.prototype.__proto__ === Object.prototype);// true
console.info(Set.prototype.__proto__ === Object.prototype);// true
Function instanceof Object;//true
Object instanceof Function;//true
instanceof 运算符用于测试构造函数的prototype
属性是否出现在对象的原型链中的任何位置。先看语法:
// object : 要检测的对象
// constructor : 某个构造函数
object instanceof constructor
instanceof
的原理就是一级一级的向上检查 object.__proto__.__proto__
是否等于 constructor.prototype
明白了instanceof
原理,加上前面的 原型链关系图
,相信这个结果就不难理解了吧。
var nullObje = Object.create(null);// 这家伙什么属性都没有。好干净
nullObje instanceof Object;// false
Object.getPrototypeOf(nullObje);//null