javascript之深入理解原型和原型链

221 阅读2分钟

原型跟原型链一直是个玄学,按照正常思维总感觉自相矛盾,自己都说服不了自己,现在让我们用最浅显的方式来理解。

例如:

function  Person(){
 }
Person.prototype.name='kk';
var person = new Person();
console.log(person.name);

构造函数Person在创建时,自动创建了一个它的原型,并且把这个原型赋值给了prototype属性

而实例对象person具有一个__proto__属性,指向prototype,从而实现Person与person之间属性和方法的继承

每个原型对象prototype又有一个constructor属性,指向它关联的构造函数Person

即为:

person.__proto__ === Person.prototype
Person.prototype.__proto__ === Object.prototype
person.__proto__.__proto__ ===  Object.prototype
Person.prototype.constructor === Person
Object.getPrototypeOf(person) ===  Person.prototype //获取对象的原型

相互关联的原型组成的链状结构就是原型链,通过__proto__连接起来

当读取实例的属性时,如果找不到,会查找原型中的属性,如果还查不到,就会找原型的原型

原型的原型也是一个对象,可以用原始的Object()构造函数生成

    var obj=new Object();
    obj.name='cc';
    console.log(obj.name);

那么Object.prototype的原型呢?Object.prototype没有原型,查找到Object.prototype就停止了

Object.prototype.__proto__ === null

原型链的主要目的是实现继承:利用原型让一个引用类型继承另一个引用类型的属性和方法

例如:

function Animal(){  
    this.type = "animal";  
}  
Animal.prototype.getType = function(){  
    return this.type;  
}  
function Dog(){  
    this.name = "dog";  
}  
Dog.prototype = new Animal();  
Dog.prototype.getName = function(){  
    return this.name;  
}   
var cc = new Dog();
console.log(cc);

原型链关系:

cc.__proto__ === Dog.prototype
Dog.prototype.__proto__ === Animal.prototype
Animal.prototype.__proto__ === Object.prototype
Object.prototype.__proto__ === null

总结:cc是Dog的实例对象,继承了Animal,Animal继承了Object

特殊的Function:

原型对象Person.prototype是普通对象,有__proto__属性,没有prototype属性

通过new Function()创建的函数对象,有prototype属性

但是Function.prototype原型对象也是函数对象,却没有prototype属性

Function.prototype.prototype === undefined
Function.__proto__ === Function.prototype //true,Function 也是函数对象,也是通过new Function()创建,自己是自己的原型
Object.__proto__ === Function.prototype // true,Object 是函数对象,是通过new Function()创建的

相关阅读:

原型链:juejin.cn/post/684490…

多种创建函数的方式:

github.com/mqyqingfeng…

louiszhai.github.io/2015/12/15/…