JavaScript专题-原型链

简介: JavaScript专题-原型链此专题系列为又一次重新阅读了《高程4》后,对JavaScript重难点进行了梳理,希望能融会贯通,加深印象,更进一步...原型定义这里通过多方面对原型进行描述,因为其实大家多多少少都接触过原型相关的知识,不理解可能只需要某句话就能点破,希望对你有所帮助。

JavaScript专题-原型链

此专题系列为又一次重新阅读了《高程4》后,对JavaScript重难点进行了梳理,希望能融会贯通,加深印象,更进一步...

原型定义


这里通过多方面对原型进行描述,因为其实大家多多少少都接触过原型相关的知识,不理解可能只需要某句话就能点破,希望对你有所帮助。

原型prototype其实就是每个构造函数的一个内置属性,或者说每个函数都有这样一个属性,毕竟所有函数都可以做构造函数,当然箭头函数除外,那只是JS简化一些写法的机制,与普通函数有一定区别。任何时候我们在创建一个普通函数时,都会按照特定的规则为这个函数创建一个prototype属性,所以我们可以访问它。

function Person(name) {
    console.log('exec...');
    this.name = name
}
Person.prototype.city = 'Beijing'
Person.prototype.skill = function(){
    console.log('coding...');
}


这个prototype属性是一个对象,这个原型对象上的属性和方法都可以被对应的构造函数创建的实例所共享,这点也是原型最重要的性质之一。

const p1 = new Person('Justin3go');
const p2 = new Person('XXX');
console.log(p1.name, p2.name);
console.log(p1.city, p2.city);
p1.skill();
p2.skill();
exec... 
exec... 
Justin3go XXX 
Beijing Beijing
coding...
coding...


值得注意的是,实例并没有prototype属性,只有构造函数拥有该属性。如果你了解new操作符的过程的话可能对此比较清楚,它只是在实例化的过程中会把构造函数的prototype赋值给实例的一个内部特性指针[[Prototype]]上,然后浏览器会在每个实例对象上暴露__proto__执行访问操作。后续ES6才规范了Object.getPrototype()方法访问原型

我们可以把原型对象作为每个相关实例的上层作用域,通俗来说就是实例上没有的变量名,会往上层作用域找,这里就是先找的自己的原型对象里面是否包含该变量名;既然是作用域,当实例上包含和原型同名的方法或属性时,访问的就只会是实例自己定义的了,这就是常说的覆盖。

这个原型对象中除了自定义的属性和方法,还有就是一个特殊的属性叫做constructor,其指向构造函数。这样,所有的实例都可以访问该属性从而获取自己的构造函数了

深入理解原型


这里我们再来梳理一下这个过程:

  1. 首先我们创建了一个构造函数想要去生成一些实例对象
  2. JS会自动给这个构造函数生成一个原型对象
  3. 然后我们基于原型的特性把想要共享的属性和方法添加到了构造函数的原型上
  4. 之后我们实例化的时候会将构造函数的原型对象赋值给实例对象中的内部指针,注意赋值不是复制,只是指向,实例和构造函数的原型都是一个
  5. 然后我们访问实例对象中的属性,发现实例本身没有,就会自动去找原型上的

然后在这个例子中,我们再来梳理一下关于构造函数、实例、原型的一个关系,下面这个图就可以非常清晰明了的表达了:

原型链


在JavaScript中,我们都知道每个对象都有一个[[Prototype]]指针指向其原型对象,而原型对象也是对象,所以原型对象也包含一个[[Prototype]]指针指向更上一层的原型对象。这就是形成我们常说的原型链的基础。

我们再简化一下这张图,让你对链的加深一下记忆:

关于原型对象中的constructor属性


这里说说我们经常见到的一个问题就是为什么不要使用对象的constructor属性来判断该对象属于哪类:


const arr1 = new Array();
console.log(arr1.constructor === Array);
function Person(){};
const p1 = new Person();
console.log(p1.constructor === Person);


true
true


constructor虽然可以拿来判断类型,但是不是百分百准确的,比如如果创建一个对象来改变它的原型,constructor就不能用来判断数据类型了

function Person(){};
Person.prototype = {
  skill: function(){
    console.log('coding...');
  },
  city: "beijing"
}
const p1 = new Person();
console.log(p1.constructor === Person);
console.log(p1.constructor);
false
[Function: Object]

这是因为我们是以对象字面量{}来直接对原型进行赋值的,而之前是通过点操作符增加属性的,前者是完全覆盖,所以原型改变了,而{}Object()的简化方式,所以此时该原型的constructor就等于Object了,所以这里就是false



目录
相关文章
|
4月前
|
JavaScript 前端开发
谈谈对 JavaScript 中的原型链的理解。
JavaScript中的原型链是实现继承和共享属性的关键机制,它通过对象的`prototype`属性连接原型对象。当访问对象属性时,若对象本身没有该属性,则会查找原型链。此机制减少内存占用,实现代码复用。例如,实例对象可继承原型对象的方法。原型链也用于继承,子类通过原型链获取父类属性和方法。然而,原型属性共享可能导致数据冲突,且查找过程可能影响性能。理解原型链对JavaScript面向对象编程至关重要。如有更多问题,欢迎继续探讨😊
29 3
|
4月前
|
JavaScript 前端开发 安全
JavaScript原型链的使用
【4月更文挑战第22天】JavaScript中的原型链是理解继承的关键,它允许对象复用属性和方法,减少代码冗余。示例展示如何通过原型链实现继承、扩展内置对象、构造函数与原型链的关系以及查找机制。应注意避免修改`Object.prototype`,使用安全方式设置原型链,并谨慎处理构造函数和副作用。
|
11天前
|
开发者 图形学 iOS开发
掌握Unity的跨平台部署与发布秘籍,让你的游戏作品在多个平台上大放异彩——从基础设置到高级优化,深入解析一站式游戏开发解决方案的每一个细节,带你领略高效发布流程的魅力所在
【8月更文挑战第31天】跨平台游戏开发是当今游戏产业的热点,尤其在移动设备普及的背景下更为重要。作为领先的游戏开发引擎,Unity以其卓越的跨平台支持能力脱颖而出,能够将游戏轻松部署至iOS、Android、PC、Mac、Web及游戏主机等多个平台。本文通过杂文形式探讨Unity在各平台的部署与发布策略,并提供具体实例,涵盖项目设置、性能优化、打包流程及发布前准备等关键环节,助力开发者充分利用Unity的强大功能,实现多平台游戏开发。
28 0
|
20天前
|
JavaScript 前端开发 开发者
揭开JavaScript的神秘面纱:原型链背后隐藏的继承秘密
【8月更文挑战第23天】原型链是JavaScript面向对象编程的核心特性,它使对象能继承另一个对象的属性和方法。每个对象内部都有一个[[Prototype]]属性指向其原型对象,形成链式结构。访问对象属性时,若当前对象不存在该属性,则沿原型链向上查找。
23 0
|
3月前
|
设计模式 JavaScript 前端开发
【JavaScript】深入浅出JavaScript继承机制:解密原型、原型链与面向对象实战攻略
JavaScript的继承机制基于原型链,它定义了对象属性和方法的查找规则。每个对象都有一个原型,通过原型链,对象能访问到构造函数原型上的方法。例如`Animal.prototype`上的`speak`方法可被`Animal`实例访问。原型链的尽头是`Object.prototype`,其`[[Prototype]]`为`null`。继承方式包括原型链继承(通过`Object.create`)、构造函数继承(使用`call`或`apply`)和组合继承(结合两者)。ES6的`class`语法是语法糖,但底层仍基于原型。继承选择应根据需求,理解原型链原理对JavaScript面向对象编程至关重要
70 7
【JavaScript】深入浅出JavaScript继承机制:解密原型、原型链与面向对象实战攻略
|
3月前
|
JavaScript
js奥义:原型与原型链(1)
js奥义:原型与原型链(1)
|
3月前
|
JavaScript 前端开发
JavaScript进阶-原型链与继承
【6月更文挑战第18天】JavaScript的原型链和继承是其面向对象编程的核心。每个对象都有一个指向原型的对象链,当查找属性时会沿着此链搜索。原型链可能导致污染、效率下降及构造函数与原型混淆的问题,应谨慎扩展原生原型、保持原型结构简洁并使用`Object.create`或ES6的`class`。继承方式包括原型链、构造函数、组合继承和ES6的Class继承,需避免循环引用、方法覆盖和不当的构造函数使用。通过代码示例展示了这两种继承形式,理解并有效利用这些机制能提升代码质量。
54 5
|
2月前
|
JavaScript C++
js【详解】原型 vs 原型链
js【详解】原型 vs 原型链
28 0
|
3月前
|
JavaScript 前端开发
JS原型链
JS原型链
20 0
|
4月前
|
前端开发 JavaScript
前端 js 经典:原型对象和原型链
前端 js 经典:原型对象和原型链
38 1