JavaScript原型对象以及原型链详解

JavaScript 常被描述为一种基于原型的语言 (prototype-based language)——每个对象拥有一个原型对象,对象以其原型为模板、从原型继承方法和属性。原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。这种关系常被称为原型链 (prototype chain),它解释了为何一个对象会拥有定义在其他对象中的属性和方法。

原型对象prototype

关于prototype属性

  1. 每个函数都有一个prototype属性,默认指向一个object空对象
  2. 原型对象中有一个属性constructor,它指向函数对象
  3. 给原型对象添加方法或者属性
每个函数都有一个prototype属性,默认指向一个object空对象 
//解析器添加了一个prototype属性,这个属性其实是一个对象 也就是我们的原型对象
var Person =function(){
        
    }

    console.log(Person.prototype)//默认指向一个Object空对象,所谓空对象是指 没有我们的属性
	
    Person.prototype.test=function(){
        console.log('test')
    }
    console.log(Person.prototype)

原型对象中有一个属性constructor,它指向函数对象
 console.log(Person.prototype.constructor==Person) //输出结果是true

关于__proto__属性

  1. 每个实例对象 都有一个__proto__属性 也就是隐式原型
  2. 对象的隐式原型的值为其构造函数的显示原型的值
 function Person() {
     
    }
    var p1=new Person()
    //每个函数都有一个prototype  也就是显示原型属性,默认指向空对象,
    console.log(Person.prototype)
    //每个实例对象 都有一个__proto__属性 也就是隐式原型
    console.log(p1._proto_)
    //对象的隐式原型的值为其构造函数的显示原型的值
     console.log(Person.prototype===p1._proto_)//输出结果是true
    
    //显示原型和隐式原型 保存的是对象的引用

图解实例、构造函数、原型对象的关系

关于prototype属性和__proto__属性有点难以理解,画了一个简单的图理解
一下构造函数、实例和原型对象的关系。

在这里插入图片描述

原型链

什么是原型链

通俗一点来讲,因为__proto__属性是每一个对象都有的属性,会形成一个由__proto__连接起来的链条,递归访问__proto__属性,必须最终到头,且是null。
JavaScript引擎查找对象属性的时候会先在对象本身查找该属性,没找到会去原型链上查找。

两个静态方法

构造函数
function School(){
 }
 School.name='西安邮电大学'
 School.change=function(){
     console.log('爱在西邮')
 }


var school =new School();

console.log(school.name)

 class Son{

    static  count;

    static eat(){
        console.log("今天吃什么")
    }

    sleep(){
        console.log('早睡早起身体好')
    }
   }

继承

继承在css部分有笔记讲到过,定义都是差不多的,举个简单的例子来看下,子类对父类的继承

//定义一个student类
    class student{

        constructor(name,age){
            
            this.name=name;
            this.age=age;
        }

        say(){
            alert('你好,'+this.name+'欢迎你的加入 ')
        }

    }
//定义一个子类继承student
  class son2 extends student{
        constructor(name,age,sex){
            super(name,age)//调用父类的构造方法
            this.sex=sex;
        }
        saylove(){
            alert('**')
        }
    }

子类对父类方法的重写

  class student{

        constructor(name,age){
            
            this.name=name;
            this.age=age;
        }

        say(){
            alert('你好,'+this.name+'欢迎你的加入 ')
        }

    }
     class son1 extends student{
        
        say(){
            alert('好好学习,天天向上')
        }
    }
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
1. 原型JavaScript 中,每个对象都有一个原型对象原型对象是一个普通的对象,其中包含了一些属性和方法。当我们访问对象的属性或方法时,如果该对象本身没有该属性或方法,JavaScript 引擎会自动去该对象原型对象中查找,如果原型对象中仍然没有,则会在原型对象原型对象中查找,一直查找到 Object.prototype,最后如果还没有找到,则会返回 undefined 。 2. 继承 在 JavaScript 中,我们可以通过继承来实现代码复用和对象之间的关系。JavaScript 中的继承有两种方式:通过原型链继承和通过构造函数继承。 3. 原型继承 原型继承是指在 JavaScript 中通过设置对象原型来实现继承的方式。具体的实现方式有很多种,其中一种比较常见的方式是使用 Object.create() 方法来创建一个新对象,并将原型指定为另一个对象。示例如下: ``` let animal = { eat() { console.log("eating"); } }; let rabbit = Object.create(animal); rabbit.eat(); // 输出 "eating" ``` 在上面的示例中,我们首先定义了一个 animal 对象,它包含一个 eat() 方法。然后我们通过 Object.create() 方法创建了一个新对象 rabbit,并将其原型设置为 animal,这样就实现了 rabbit 对象从 animal 对象继承 eat() 方法的功能。我们可以通过调用 rabbit.eat() 来验证该方法确实存在于 rabbit 对象中。 4. 关键字 在 JavaScript 中,有一些关键字和函数可以用来实现原型继承。其中最常用的关键字是 extends 和 super。 extends 关键字可以用来继承一个类,示例如下: ``` class Animal { eat() { console.log("eating"); } } class Rabbit extends Animal { run() { console.log("running"); } } let rabbit = new Rabbit(); rabbit.eat(); // 输出 "eating" rabbit.run(); // 输出 "running" ``` 在这个示例中,我们首先定义了一个 Animal 类,并为其定义了一个 eat() 方法。然后我们定义了一个 Rabbit 类,该类使用 extends 关键字继承了 Animal 类,并为其定义了一个 run() 方法。我们通过实例化 Rabbit 类来创建一个 rabbit 对象,并通过调用 rabbit.eat() 和 rabbit.run() 来验证其继承效果。 super 函数用于在子类中调用父类的同名方法。示例如下: ``` class Animal { constructor(name) { this.name = name; } speak() { console.log(this.name + " makes a noise."); } } class Dog extends Animal { constructor(name) { super(name); } speak() { console.log(this.name + " barks."); } } let dog = new Dog("Rex"); dog.speak(); // 输出 "Rex barks." ``` 在这个示例中,我们首先定义了一个 Animal 类,并为其定义了一个构造函数和一个 speak() 方法。然后我们定义了一个 Dog 类,该类继承了 Animal 类,并为其定义了一个构造函数和一个 speak() 方法。 在 Dog 类的构造函数中,我们调用了父类的构造函数,并传入了 name 参数。在 Dog 类的 speak() 方法中,我们使用 super 函数调用了父类的同名方法,并将其重写为输出“barks.”。我们通过实例化 Dog 类来创建一个 dog 对象,并通过调用 dog.speak() 来验证其继承效果。 总结 在 JavaScript 中,原型继承是一种非常重要的对象复用和代码组织方式。我们可以使用原型对象来实现原型继承,也可以使用关键字和函数来简化继承的过程。在实际开发中,我们需要根据具体的业务场景和需求来选择最合适的继承方式和实现方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值