likes
comments
collection
share

JS原型链

作者站长头像
站长
· 阅读数 44

注:理解原型链对于小白属实有点绕,这里分几个章节来讲解

一.对象

众所周知,JS是面向对象编程的弱类型语言,对象几乎涵盖了JS的所有----------万物皆对象。

那么创建对象的方式有哪些呢?

1.方法一

通常object的代码表现形式是{},所以我们可以直接如下,定义一个对象

var obj={
    name:'龙儿哥哥',
    age:26,
    SayHi:function(){
        console.log('龙儿哥哥向你打了一个招呼!');
    }
}
obj.age;//26
obj.Say();//龙儿哥哥向你打了一个招呼

2.方法二

我们知道,创建一个日期对象数组等使用的是new关键字进行创建,同样,普通对象也能使用new关键字创建。

var obj=new Object();
obj.name="龙儿哥哥";
obj.age=26;
obj.SayHi=function(){
    console.log('龙儿哥哥向你打了一个招呼!');
}

3.方法三

区别于传统意义上的对象,这里我们要使用一个函数创建一个对象-------------构造函数,这也是这一章节的重点。

  function person(){
    this.name = '龙儿哥哥'
  }
  let pers = new person()
  console.log(pers.name);//龙儿哥哥

二.什么是原型

注:

对象的常见访问形式:obj.name, obj['name']
常见的浏览器解析引擎的内置方法__proto__,访问的是当前对象的原型(项目中不建议使用__proto__访问原型)

1.为了便于理解给出以下例子

  function Person(){
    this.name = '龙儿哥哥'
  }
  let pers = new Person()
  console.log(pers);
  console.log(pers.__proto__);

打印结果如下图所示

JS原型链

(1)通过打印pers,可以清晰的看到pers是一个对象,其下有一个name属性,值为'龙儿哥哥',pers就是一个实例对象name则为这个实例对象pers实例属性

(2)通过第二条,我们打印了pers.proto ,所以打印结果指向的是pers这个实例对象原型。通过以上代码打印结果我们知道红色框内的是一摸一样的数据,也就是说这两个红色框内东东就是pers实例对象原型(访问对象原型时不建议使用__proto__,这里打印单纯为了讲解,项目中请使用getPrototypeOf(obj)访问对象原型)

(3)可以看到这个原型中存在两个属性:

一个是construtor,其值为Person这个函数,由此可见这个construtor指向的就是这个构造函数本身。

第二个使用 [[]] 包裹的Prototype属性,其Object,这个prototype就是pers这个实例对象原型对象

三.原型对象

1.第二章我们知道了什么是实例对象,什么是原型, 什么是原型对象以及 proto指向问题,这一章我们就深入理解实例对象原型对象以及他们的关系

	function Person(){
		this.name = '龙儿哥哥'
	}

	let obj = {
		age:18
	}
	
	let pers = new Person()

	Person.prototype.age = 18 //此方法给默认的原型设置属性,当存在Object.setPrototypeOf时此操作不生效,按需设置

	// Object.setPrototypeOf(pers,obj) //为对象设置原型,替换原有原型对象,原对象原型将不生效

	console.log('实例对象',pers)
	console.log('属性值',pers.age)
	console.log('原型',pers.__proto__) // 一般浏览器内置方法,项目中不建议使用
	console.log('原型',Object.getPrototypeOf(pers)) // 项目中采用此方法访问对象原型

打印结果如下

JS原型链

从打印结果看

(1).实例通过__proto__Object.getPrototypeOf()访问的就是一个对象的原型,原型也是一个对象

(2).通过第二个打印,我们访问了实例对象pers的age属性,打印的结果是实例对象的原型中的属性,当一个实例对象中不存在某个属性时,JS解析引擎(浏览器)会自动向原型中查找该属性。

(3).__proto不作为公开的API,避免在项目中使用。应当使用基于ES6规范的Object.getPrototypeOf()进行访问对象的原型

(4).实例对象的属性优先级高于原型中属性,如上例子:如果实例perspers的原型中都存在age属性,打印pers.age访问的将是实例中的age属性

(5).打印一个对象,可以看到当中有[[ProtoType]]:Object,展开后可以发现当中存在很多方法,这些方法其实是JS引擎自动提供的原型方法,这使得我们可以正常的使用字符串数组,对象日期的一些API。

2.什么是构造函数

	function Person(){
		this.name = '龙儿哥哥'
	}

	let pers = new Person()

	let animal = {
		type:'泰哥'
	}
	console.log('实例对象',pers)
	console.log('实例对象',animal)
打印结果如下

JS原型链

JS原型链

从打印结果看

(1)打印的内容中有constructor函数,这个函数就是构造函数

(2)通过构造函数创建的对象,其构造函数为当前函数;通过new Object{}创建的对象,其构造函数是JS引擎自动创建的,其中有很多方法可通过示例进行调用。

(3) 构造函数的主要作用是在创建对象时初始化对象,即为对象的成员变量赋初始值

四.原型链

1.通过以上三章,我们能能大体了解到什么是对象实例,原型,原型对象,构造函数;

对象:在JS中万物皆“对象”,除了null,undefined空值。(可以创建一个变量,然后通过访问其__proto__属性),这里所说的“对象”只作为举例参考,并不作为变量类型判断依据

实例:将一个对象赋值给一个变量后,这个变量就是实例,let obj = {},let obj1 = new Object(),let obj2 = new function(){},这里的obj1,obj2,obj3都是实例。

原型:实例通过__proto__Object.getProtoTypeOf()访问到的就是原型,原型包含原型对象构造函数

构造函数:跟普通函数一样,是创建对象的基本函数,但是普通函数不一定是构造函数。

原型对象:如果通过Object.setProtoTypeOf(obj1,obj2),那么obj2就是原型对象,也可以说原型中除去构造函数部分就是原型对象。

JS原型链 参见上图:就是这几者之间的关系

2.理解了实例,原型,构造函数,我们再来探讨一下原型

function Person(){
        this.name = '龙儿哥哥'
}
let pers = new Person()

console.log('pers',pers) //当前实例
console.log('pers',pers.__proto__) //原型
console.log('pers',pers.__proto__.__proto__) // null
        

(1)我们知道实例通过__proto__访问到的是原型,继续链式调用__proto__访问的则是原型的原型,直至最终值为null;

	let pers = new function Person(){
		this.name = '龙儿哥哥'
	}
	let obj1 = {
		age:18
	}
	let obj2 = {
		sex:'男'
	}
	Object.setPrototypeOf(obj1,obj2)
	Object.setPrototypeOf(pers,obj1)
	console.log('pers',pers) //实例pers
	console.log('pers',pers.__proto__) // obj1
	console.log('pers',pers.__proto__.__proto__) // obj2
	console.log('pers',pers.__proto__.__proto__.__proto__) // obj2的原型
	console.log('pers',pers.__proto__.__proto__.__proto__.__proto__) // null

不理解代码可以参考下图:

JS原型链

(2)我们可以知道通过 new关键字创建实例对象,通过__proto__Object.getPorotoTypeOf()访问原型,通过Object.setProtoTypeOf()来设置原型。

总结:揭开原型链的面纱,原型链就是实例构造函数原型以及__proto__之间的指向关系。

补充:最后一张图是面试重点,也是会写javascript的入门条件喔,一定要记牢

转载自:https://juejin.cn/post/7376527773946118184
评论
请登录