javascript原型对象、原型链学习感悟

281 阅读3分钟

一些废话

最近在前端进击之路上遇到了一些阻碍,之前工作用的都是一些基于类的面向对象语言,遇到了js就有点懵逼了,这继承咋整,原型对象是啥,原型链又是啥啥,最让人头大的就是红宝书原型链开头那一段复杂拗口的话语,还是赶紧来掘金看看大佬们精彩的解析。

首先要贴出救我于水火的文章,这篇文章真的简洁明了,看完后顿觉茅塞顿开,感慨万千,决定写下来,方便以后。

一些概念和原则

一些概念

1、js对象分为普通对象和函数对象,每个对象都有__proto__属性,但不是每个对象都有prototype属性,只有函数对象才有。

2、属性__proto__也是一个对象,它也有__proto__属性,但还有一个constructor属性;原型对象有一个默认的constructor属性,指向实例的构造函数。

一些原则

1、原型对象(prototype属性)指向其构造函数本身,即Test.prototype.constructor == Test,如下图

2、实例的__proto__属性指向的是原型对象,即test.__proto__ == Test.prototype,如下图

var Test = function() { };
var test = new Test();

console.log(Test.prototype.constructor);
console.log(Test.prototype.constructor == Test);

console.log(test.__proto__);
console.log(test.__proto__ == Test.prototype);

WechatIMG61.png

一些理解

js因为没有基于类的东西,所以该如何玩面向对象继承那一套呢,就是原型链。

例如上面的var Test = function() { }就相当于我们定义了一个名字叫做Test的类,而此时我们定义一个子类TestSon,通过将一个Test类的实例化赋予给TestSon类的prototype属性,实现了TestSon类对Test类的继承,即TestSon.prototype = new Test();

这样子类的实例化不仅可以访问到子类的属性和方法,同样也可以通过原型链层层查找,访问到父类的属性和方法。当然如果你在子类的实例化里添加或修改了父类里同名的属性或方法,则对其进行了重写,之后再对其访问的时候访问到的即为子类实例化自身的属性方法了,不再是父类里的。(当然你也可以直接修改父类里的属性和方法,不会重写,不过这样其他的父类实例和子类实例调用到的属性方法也会被修改,因为他们是共有的)

一些例子

本例子是学习时改着玩的,个人觉得思想上没啥问题。

// 父类
var Menu = function () {
    this.name = '菜单';
}

Menu.prototype = {
    GetName: function () {
        return this.name;
    }
}

// 子类
var MenuLanguage = function () {
    this.currentLanguage = 'chn';
    this.ShowInfo = function () {
        console.log(this.currentLanguage);
        console.log(this.GetName());
    }
}

// 继承
MenuLanguage.prototype = new Menu();


var languageMenu = new MenuLanguage();
languageMenu.ShowInfo();

父类为菜单类,拥有自己的属性。子类为语言菜单类,通过MenuLanguage.prototype = new Menu();对父类进行了继承,继承了Menu.prototype中的方法GetName(),并有自己的属性和方法。最后实例化了一个语言菜单,调用方法打印,不仅访问到了语言菜单自身的属性,同时也访问到了父类菜单类的属性,如下图

WX20210603-170753@2x.png

一些其他图片

截屏2021-06-03 下午5.09.19.png

一些其他废话

本文是一个记录备忘的目的,所以难免会不够准确甚至错误,毕竟只是个前端小白,刚刚开始学习。欢迎大家路过指正。