js奥义:原型与原型链(1)

简介: js奥义:原型与原型链(1)

要弄懂原型链,首先应先明白prototype原型对象、__proto__、对象三者之间的关系。

引入构造函数的相关定义:

  构造函数是一种比较特殊的函数,用于批量实例化对象。通俗一点说,构造函数是用于生成对象的模板

由于工厂模式在实例化对象时会存在同一功能代码在内存中开辟不同内存空间从而造成内存空间浪费的问题,更多的人选择使用构造函数来实例化对象,es6中引进的class关键字正是基于构造函数的思想

构造函数的本质上是将对象中一些公共的方法和属性 抽取出来,然后将这个函数封装成可复用的构造函数.

 构造函数的特点(与工厂函数相比较):    

    a. 函数名首字母大写;

    b.  函数体内没有关键字new,在实例化一个对象时会使用关键字new;

    c.  构造函数体内的this指代当前实例化对象;

    d.   函数体内没有关键字return。

 function Fn() {
            this.n = 20
        }
        Fn.prototype.say= function() {
            console.log(this.n)
        }
        var deb = new Fn()

 构造函数的new关键字在实例化对象时会做以下四件事:

  a.现在内存中开辟一块内存空间(new obj);

  b.让构造函数体内的this指向这个对象   (因而,this指代当前对象);

  c.将构造函数体内的属性和方法赋值给这个这个对象;

  d.返回这个对象 (因而,构造函数体内没有return关键字)

为了区别对待,以下将构造函数称为父类,将实例化对象称为子类。


一:原型


  1.定义

 每一个函数身上都有一个prototype(原型),由于这个prototype的值是一个对象类型,因而又叫做原型对象,ptototype属性是函数独有的属性!

  2.原型的作用

  原型对象的作用通常用来共享父类的方法,由于方法是函数,本质上也是一个对象,而对象的内存地址保存在堆空间里,如同工厂模式一般,多个内存空间存放相同的代码,会造成大量空间被占用,因而将公有的方法添加在父类的prototype上,也就是写入了同一对象上,调用的时候也就避免了多个空间存放同一代码的错误示范,而由于父类的属性的值是基本类型,所占内存较少,所以我们往往将其添加到父类函数体的内部。

  function Fn() {
            this.n = 20
        }
        Fn.prototype.sing = function() {
            console.log(this.n)
        }
        var deb = new Fn()
        var deb2 = new Fn()
        console.log(deb.sing === deb2.sing) //true

 

二:__proto__


  与函数的prototype属性不同,每一个obj的对象都有一个__ptoto__属性,这个__proto__属性隐式的指向了这个子类的的构造函数的prototype属性!但是这个__proto__属性是不可见的,这也就是为什么将其称作是隐式的,不过好在浏览器的支持下,它被定义为__proto__

  如果看到这里,希望你再好好思考一下 ”万物皆对象“这句话的含义

  从父类的角度看,子类的_proto_属性隐式指向了它的父类的prototype对象;从子类的角度看,子类自身的__proto__属性指向了它的父类的prototype属性

  假如我们对比父类的prototype与子类的__proto__属性:

console.log(Fn.prototype === deb.__proto__)//true

  理解了这一点,就可以明白为什么构造函数添加在其原型对象上的方法,实例化对象可以共享使用了:因为构造函数的prototype属性指向的实例化对象的__proto__属性指向是同一个对象,也就是父类的prototype对象


这样,就具备了深入理解原型链的条件。

相关文章
|
2月前
|
JavaScript 前端开发
js开发:请解释原型继承和类继承的区别。
JavaScript中的原型继承和类继承用于共享对象属性和方法。原型继承通过原型链实现共享,节省内存,但不支持私有属性。
24 0
|
2月前
|
JavaScript 前端开发 安全
JavaScript原型链的使用
【4月更文挑战第22天】JavaScript中的原型链是理解继承的关键,它允许对象复用属性和方法,减少代码冗余。示例展示如何通过原型链实现继承、扩展内置对象、构造函数与原型链的关系以及查找机制。应注意避免修改`Object.prototype`,使用安全方式设置原型链,并谨慎处理构造函数和副作用。
|
12天前
|
设计模式 JavaScript 前端开发
【JavaScript】深入浅出JavaScript继承机制:解密原型、原型链与面向对象实战攻略
JavaScript的继承机制基于原型链,它定义了对象属性和方法的查找规则。每个对象都有一个原型,通过原型链,对象能访问到构造函数原型上的方法。例如`Animal.prototype`上的`speak`方法可被`Animal`实例访问。原型链的尽头是`Object.prototype`,其`[[Prototype]]`为`null`。继承方式包括原型链继承(通过`Object.create`)、构造函数继承(使用`call`或`apply`)和组合继承(结合两者)。ES6的`class`语法是语法糖,但底层仍基于原型。继承选择应根据需求,理解原型链原理对JavaScript面向对象编程至关重要
24 7
【JavaScript】深入浅出JavaScript继承机制:解密原型、原型链与面向对象实战攻略
|
13天前
|
JavaScript 前端开发
JavaScript进阶-原型链与继承
【6月更文挑战第18天】JavaScript的原型链和继承是其面向对象编程的核心。每个对象都有一个指向原型的对象链,当查找属性时会沿着此链搜索。原型链可能导致污染、效率下降及构造函数与原型混淆的问题,应谨慎扩展原生原型、保持原型结构简洁并使用`Object.create`或ES6的`class`。继承方式包括原型链、构造函数、组合继承和ES6的Class继承,需避免循环引用、方法覆盖和不当的构造函数使用。通过代码示例展示了这两种继承形式,理解并有效利用这些机制能提升代码质量。
|
10天前
|
JavaScript 前端开发
JS原型链
JS原型链
8 0
|
2月前
|
前端开发 JavaScript
前端 js 经典:原型对象和原型链
前端 js 经典:原型对象和原型链
31 1
|
2月前
|
JavaScript 前端开发
在JavaScript中,函数原型(Function Prototype)是一个特殊的对象
【5月更文挑战第11天】JavaScript中的函数原型是一个特殊对象,它为所有函数实例提供共享的方法和属性。每个函数在创建时都有一个`prototype`属性,指向原型对象。利用原型,我们可以向所有实例添加方法和属性,实现继承。例如,我们定义一个`Person`函数,向其原型添加`greet`方法,然后创建实例`john`和`jane`,它们都能调用这个方法。尽管可以直接在原型上添加方法,但推荐在构造函数内部定义以封装数据和逻辑。
32 2
|
2月前
|
JavaScript 前端开发
前端 JS 经典:原型和原型链
前端 JS 经典:原型和原型链
26 0
|
2月前
|
JavaScript 前端开发
JavaScript 原型链继承:掌握面向对象的基础
JavaScript 原型链继承:掌握面向对象的基础
|
2月前
|
JavaScript 前端开发
JavaScript原型链:工作原理与深入探究
【4月更文挑战第22天】JavaScript原型链是对象属性查找的关键,它通过对象间的链接形成链式结构。当访问属性时,JS从对象自身开始查找,若未找到则沿原型链向上搜索,直至`null`。原型链用于继承、扩展内置对象和实现多态,但要注意避免修改内置对象原型、控制链长度及使用`Object.create()`创建对象。理解并合理运用原型链能深化JS面向对象编程的理解。