一 前言
最近学习到JavaScript的原型以及原型链相关知识,看到了冴羽的文章(传送门),让我对原型以及原型链有了一定了解,但是读完似乎还有点意犹未尽,关于Object和Function的原型链部分就戛然而止了,这篇文章我就着重写写我对这部分的理解。
二、 基础概念梳理
2.1 原型
每一个JavaScript对象(null除外)都和另一个对象相关联。这里的“另一个对象”指的就是原型。
2.2 _proto_和prototype
既然有了原型,那么我们就需要有具体所指。我们既可以用我们创造的对象的_proto_属性指代这个对象的原型,同时这个对象的原型也是创造这个对象所用到的构造函数的prototype属性的值。
2.3 原型链
一系列链接的原型对象就是所谓的“原型链”。即当我们访问一个对象的属性值的时候,它会沿着原型链(通过对象的_proto_属性)向上查找,直到找到或者Object.prototype.proto(为null)截止。
三、 分析原型链中Object,Function以及构造函数之间的关系
话不多说,先祭图
3.1 看①②两条线
Foo._proto_ === Function.prototype
Object._proto_ === Function.prototype
复制代码
说明这里Foo,Object除了本身是f1,f2,o1,o2实例对象的构造函数外,自己本身还是Function的实例对象。Foo,Object构造函数本身也是一个对象。
3.2 看③这条线
Function.prototype._proto_ === Object.prototype
复制代码
说明Function.prototype原来是Object的实例对象。现在在想想为什么说函数就是对象,因为任何函数的原型都能追溯到Function.prototype ,而Function.prototype的原型就是Object.prototype。
3.3 看④⑤两条线
Function._proto_ === Function.prototype
复制代码
3.3.1 鸡生蛋还是蛋生鸡?
这里借用冴羽文章中的解释,Function作为一个内置对象,是在运行前就已经存在的东西,所以是先有的Function,然后实现上把原型指向了Function.prototype,为了跟其他函数保持统一。
3.3.2 Function本身也是对象
根据3.2给出关系结合3.3可以得出
Function._proto_._proto_ === Object.prototype
复制代码
即Function的原型的原型也是Object.prototype。
4 万物皆对象
在JS中我们知道万物皆对象,那为啥这么说呢,我的理解是,从原型链来看,你会发现万物的根源就是Object.prototype。
5 小试牛刀
如题
var foo = {},
F = function(){};
Object.prototype.a = 'value a';
Function.prototype.b = 'value b';
console.log(foo.a); //value a
console.log(foo.b); // undefined
console.log(F.a); // value a
console.log(F.b); // value b
复制代码
分析:
- foo.a, foo对象没有找到去找foo._proto_即Object.prototype找到属性a的值为'value a'
- foo.b,foo对象没有找到去找foo._proto_即Object.prototype还是没有找到去找foo._proto _._proto_即null也没有找到属性b,所以输出undefined
- F.a,F对象没有找到去找F._proto_即Function.prototype还是没有找到去找F._proto _._proto_即Object.prototype找到属性a的值为'value a'
- F.b,F对象没有找到去找F._proto_即Function.prototype扎到属性b的值为‘value b’