欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JavaScript之原型和原型链

程序员文章站 2022-06-10 19:17:25
...

JavaScript之原型和原型链

在JavaScript的学习过程中,原型链肯定是一个很重要的知识点,下面我们就来深入的去看一下原型链

原型

首先看一个很简单的例子

function Person(name, age) {
            this.name = name;
            this.age = age;
            this.sayName = function () {
                console.log("i am "+this.name);
            }
        }
        Person.prototype.sayAge = function () {
            console.log("i am "+this.age);
        }
        var person1 = new Person("ljm",18)
        person1.sayAge();
        person1.sayName();
        var person2 = new Person("lll",20);
        person2.sayAge();
        person2.sayName();

控制台输出的是,和大多数人预想的一样,输出了两个person的年龄和姓名

JavaScript之原型和原型链

在这个过程中我们创建了两个实例对象(person1,person2),有一个构造函数(Person)和原型(Person.prototype),那么他们之间的关系应该是这样的

在这里插入图片描述
在这个关系上我们可以看出

  1. 每个函数上面都有一个属性(prototype)指向了函数的原型对象(Person.prototype)。
  2. 每个实例上面都有一个隐式原型(proto)指向了函数的原型对象,如本利的p1对象有一个隐式原型也指向了Person.prototype对象。
  3. 每个函数的原型对象上面都有一个constructor属性,指向了构造函数本身。

实例的(person1,person2)的__proto__也是Person.prototype

JavaScript之原型和原型链

那么在实例访问属性或者方法的时候应该遵循什么样的原则?

  1. 如果实例上面存在,就用实例本身的属性和方法。
  2. 如果实例上面不存在,就会顺着__proto__的指向一直往上查找,找到就停止,找不到就报错。
function Person(name, age) {
            this.name = name;
            this.age = age;
            this.sayName = function () {
                console.log("i am "+this.name);
            }
        }
        Person.prototype.sayAge = function () {
            console.log("我是原型上的sayAge");
        }
        var person1 = new Person("ljm",18)
        person1.sayAge = function () {
            console.log("我是person1上的sayAge")
        }
        person1.sayAge();
        person1.sayName();
        var person2 = new Person("lll",20);
        person2.sayAge();
        person2.sayName();
		person2.sayHello();

那么输出的结果就是

JavaScript之原型和原型链

如果找不到这个方法,就报错

在这里插入图片描述
虽然person1和person2都输出了sayAge方法,可是这两个方法是不一样的

JavaScript之原型和原型链

原型链

那么在刚刚这个输出sayAge过程大概可以这样描述:

在person1上有sayAge,所以输出的就是person1上的sayAge

在person2上没有sayAge,但是在person2的原型上有sayAge,所以输出的就是person2上的sayAge

简单点说就是,如果我自己有,我就用我自己的;如果我没有,则去我的上一级找;这样就形成了一条原型链。上一节中Person的原型其实还有一属性__proto__,他指向了上一级Object的原型对象。

JavaScript之原型和原型链
Object.prototype可以说是原型中的最高层,那么最终原型链应该是这样的

JavaScript之原型和原型链

原型和实例之间的判断

  1. 使用instanceof

            console.log(person1 instanceof Person)//true
            console.log(person1 instanceof Object)//true
    
  2. 使用isPrototypeOf()方法

            console.log(Object.prototype.isPrototypeOf(person1))//true
            console.log(Person.prototype.isPrototypeOf(person1))//true
            console.log(Function.prototype.isPrototypeOf(person1))//false
    

在ES6中的新运用

在ES6中,新运用了class来对JavaScript的语法更加加以完善。

在其他语言中,例如java,就有类(class),里面有构造函数(constructor),属性,方法等

所以在ES6中,为了弥补之前的不足,新推出了class

在以前的js中,生成一个对象实例,需要先定义构造函数,然后通过prototype 的方式来添加方法,再生成实例,但是现在ES6可以这样写

        class Person{
            constructor(age,name){
                this.age = age;
                this.name = name;
            }
            sayName(){
                console.log("我是"+this.name)
            }
        }
        var person1 = new Person(18,"ljm")
        console.log(person1.name)//ljm
        console.log(person1.age)//18
        person1.sayName()//我是ljm

在ES5中原本的构造函数被constructor 替代,本来需要定义在prototype上面的,方法直接定义在class里面即可。

继承

在ES6中可以使用extends来继承类(和java差不多)

class Student extends Person{
            constructor(age,name,className){
                super(age,name);
                this.className = className;
            }
            sayClass(){
                console.log("我是"+this.className)
            }
        }
        var student1 = new Student(19,"ljm","四班");
        console.log(student1.age)//19
        console.log(student1.name)//ljm
        console.log(student1.className)//四班
        student1.sayClass()//我是四班
        student1.sayName()//我是ljm

在ES5中prototype的继承

        function Person(age,name) {
            this.age = age;
            this.name = name;
        }
        Person.prototype.sayName = function () {
            console.log("我是"+this.name)
        }
        function Student(age,name,className) {
            Person.call(this,age,name);
            this.className = className;
        }
        Person.prototype.constructor = Student;
        Student.prototype = new Person;
        Student.prototype.sayClass = function () {
            console.log("我是"+this.className)
        }
        var student1 = new Student(19,"ljm","四班")
        student1.sayClass();
        student1.sayName();

在ES6语法上更加便捷

相关标签: 前端 笔记