JS中的prototype和原型链的理解

大家好,我是第一次写博客,说不定未来就会经常和大家见面啦,主要目的上希望通过分享知识的方式来总结自己的学习,希望能够通过分享,知道自己的不足。

其实我们每创建一个构造函数都有一个prototype(原型)属性
1、prototype属性更相当于是一个指针,指向另一个对象。
2、这个对象的所以方法和属性,都会被构造函数拥有。
3、我们可以把需要共享的属性定义在prototype上。

//构函函数
function Person(){

  }
Person.prototype.name = "张三"        //原型对象
let person = new Person;                //实例对象
console.log(person.name)                

查找规则:先查找自己构造函数中,再去找prototype中的

对象的三角关系:

一、每个构造函数都有一个默认的属性,叫prototype,prototype属性保存着一个对象,这个对象我们称之为原型对象
二、每个原型对象都有一个默认的属性,叫constructor。constructor指向当前原型对象对应的构造函数
三、通过构造函数创建出来的对象我们叫实例对象。每个实例对象都有一个默认的属性,叫做__proto__
四、__proto__指向创建他的那个构造函数的原型对象
如下图所示:

prototype1.png

function Person(){

  }
Person.prototype.name = "张三"          //原型对象
let person = new Person;                //实例对象

console.log(person.name);         //张三
console.log(Person.prototype) ;       //构造函数的prototype指向原型对象
console.log(person1.__proto__) ;      //实例对象的__proto__指向原型对象
console.log(Person.prototype.constructor);   //constructor,构造函数的原型对象最后指向构造函数
console.log(person1.__proto__.constructor);  //constructor,实例化的原型对象指向构造函数

构造函数.prototype和实例对象.__proto__ 的指向都是指向原型对象

console.log(person.__proto__ === Person.prototype);  //true

constructor指向当前原型对象对应的构造函数

console.log(Person.prototype.constructor);   //constructor,原型对象指向构造函数
console.log(person1.__proto__.constructor);  //constructor,原型对象指向构造函数

验证一下,函数Person 全等于原型对象点上constructor

console.log(Person === Person.prototype.constructor);   //true

实例与原型

一、当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止。
听不懂看下方 ↓

function Person() {

}
//给Person添加了name属性,
Person.prototype.name = '张三';
var person = new Person();

person.name = '李四';  //这里给person对象添加了一个name属性
//打印person对象的name属性
console.log(person.name) // 李四
delete person.name; //删除person的name属性
console.log(person.name) // 张三   

从person对象中找不到name属性,就会从person的原型中查找,因为person的原型中找到了name属性,结果为张三

delete person.name; //删除person的name属性
console.log(person.name) // 张三 

原型的原型

理解:
1、JavaScript中的函数是引用类型(对象类型),既然是对象,所以也是通过构造函数创建出来的, “所有函数”都是通过Function构造函数创建出来的对象
2、JavaScript中只要是"函数",就有prototype属性。Function函数的prototype属性指向Function原型对象
3、JavaScript中只要有原型对象就有constructor属性。Function原型对象constructor指向它对应的构造函数
4、JavaScript中万物皆对象,只要是对象就有__proto__属性

一、JavaScript中万物皆对象,只要是对象就有__proto__属性,原型的原型,直接用__proto__指向

function Person(){

  }
Person.prototype.name = "张三"          //原型对象
let person = new Person;                //实例对象
console.log(person.__proto__.__proto__)    // 原型对象的原型对象就是Object

二、原型对象也是一个对象,既然是对象,我们就可以用最原始的方式创建它。

let obj = new Object();
obj.name = '张三'
console.log(obj.name)
        
console.log(obj.__proto__)    //原型也是一个对象,对象的原型就是Object

经过验证得知:原型对象的原型对象,就是Object
现在我们再验证一下

function Person() {

}
Person.prototype.name = "张三"          //原型对象
let person = new Person;                //实例对象
console.log(person.__proto__.__proto__)  //原型对象的原型对象Object

var obj = new Object();
obj.name = 'Kevin'
console.log(person.__proto__.__proto__ === Object.prototype)  //true
console.log(obj.__proto__ === Object.prototype) //true

person.__proto__.__proto__ === Object.prototype 结果为true,全等于
obj.__proto__ === Object.prototype 结果为true

prototype2.png

原型链

一、简单的回顾一下构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针,原型对象的原型上Object。
二、原型对象也是对象,这里我就创建一个Object来演示
原型对象的原型对象的原型为null,表示没有对象

var obj = new Object();
        obj.name = 'Kevin'

        console.log(Object.prototype.__proto__) //null
        console.log(Object.prototype.__proto__ === null) // true

Object.prototype的原型对象为空
三、null表示没有对象,所以Object.prototype.__proto__ 的值为 null 跟 Object.prototype 没有原型,其实表达了一个意思,所以查找属性的时候查到 Object.prototype 就可以停止查找了。

(拓展)之前我们讲过,每个对象都有一个默认的属性,叫constructor。既然原型对象的原型对象是一个对象,那他就有constructor属性。constructor指向它对应的构造函数

var obj = new Object();
        obj.name = 'Kevin'
console.log(Object.prototype.constructor)   //Object()

Object.prototype关联的构造函数指向Object()

既然Object.prototype.constructor是指向一个构造函数,那么只要是构造函数都有一个prototype属性,在前面已经讲过了,那么我们现在在看看Object( )的prototype指向哪?

console.log(Object.prototype.constructor.prototype)  //Object

Object.prototype.constructor的原型对象指向构造函数Object
我们继续进一步验证

console.log(Object.prototype.constructor.prototype === Object.prototype) //true

Object.prototype.constructor的原型对象指向构造函数Object.prototype.constructor


prototype3.png

其实,到这里原型链就讲的差不多了,原型链就是一层一层的向上找,先查找当前对象, 当前对象有就使用当前对象的方法,当前对象没有再逐层在原型链上查找, 最先找到那个就使用哪个,如果找到null都没找到就报错

谢谢大家!!!!
如果有讲解的不对大家可以在下方留言

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):