万物皆对象,js中其实也是只有一种结构:对象。每个实例对象(object)都有一个私有属性(__proto__),同时指向它的构造函数的原型对象(prototype),该原型对象也有自己的原型对象(__proto__),层层向上直到一个原型对象为null,null没有原型,并作为这个原型链的最后一个环节。
在js中,几乎所有的对象都是位于原型链顶端的Object的实例中
const arr =[]
arr.__proto__ === Array.prototype //true
arr.__proto__.__proto__ === Object.prototype //true
arr.__proto__.__proto__.__proto__ ===null //true
// 继承关系链
// arr -> Array.prototype -> Object.prototype -> null
解释一下:arr是Array的实例对象,使用字面量方式创建了对象实例。
和上面解释的一下,每一个对象都有一个私有属性(__proto__)指向它的构造函数的原型对象(prototype)
// arr 的构造函数是Array,所以arr.__proto__指向构造函数Array的原型对象。
arr.__proto__ === Arrar.prototype // true
原型对象也有自己的原型对象(__proto__)
// Array.prototype也是对象,也有自己的原型对象,它的原型对象是Object.prototype
arr.__proto__ =Array.prototype
Array.prototype.__proto__=Object.prototype
arr.__proto__.__proto__ === Object.prototype // true
层层向上,直到一个对象的原型对象为null为止。到达了最后一个环节
Object.prototype.__proto__ === null
arr.__proto__.__proto__.__proto__ === null
关于原型链上属性的查找:
当我们访问对象的属性或者方法时,会先从对象本身开始查找,如果查找不到,则查找对象的 __proto__,层层向上查找,知道查找不到属性,否则抛出错误。
原型链结论:
1、对象实例__proto__ = 对象构造函数.prototype
2、几乎所有的对象原型都是Object.prototype
3、null是对象,但是null没有原型
4、属性/方法查找采用优先返回机制
函数
函数也是对象,但是函数的私有属性(__proto__)并不指向Object.prototype
为什么?
Object是对象的构造函数,同时构造函数也是函数,所有的函数原型都是Function.prototype。所以Object.__proto__ === Function.prototype
结论:
Object.__proto__ === Function.prototype
Array.__proto__ === Function.prototype
函数结论:
函数的原型都是 Function.prototype,构造函数也是函数。所以构造函数的原型也是Function.prototype
案例分析:
function A() {
// this 指向 函数A本身,函数本身没有属性a 此时去原型上找,可以找到原型上有a属性==1
console.log(this);
}
function B(a) {
// this 指向函数B。将属性a给函数B复制,但是a的值为undefined,但是在函数B的原型上有a属性==1
console.log(this);
this.a=a
}
function C(a) {
// this 指向函数C。在函数本身没有属性a,继续向原型上找,直到最后为null或者找到为止
console.log(this);
if (a) {
this.a=a
}
}
A.prototype.a=1;
B.prototype.a=1;
C.prototype.a=1;
console.log(new A().a) //1 在原型上可以找到a==1
console.log(new B().a) //undefined 函数本身有a属性,但是a值为undefined
console.log(new C().a) //1 在原型上可以找到属性啊==1
查找对象身上的属性,首先是在本身查找,如果没有,则去它原型上去查找,知道找到或者为null为止。
function F() {
this.a=1
}
F.prototype.b=2
var f=new F();
console.log(f.hasOwnProperty('a')); // true
console.log(f.__proto__); // f.__proto__ == F.prototype
console.log( F.prototype);
console.log(f.hasOwnProperty('b')); // false b是f的原型对象F.prototype的属性,不是b自身的