原型(prototype)、原型链(_proto_)、类

引用数据类型分类

  • 函数数据类型:
  • 普通函数
  • 内置类(如 ArrayDate)
  • 自己创建的类(只要是new创建出来的都是类)
  • 对象数据类型:
  • 普通对象、数组、正则、Math、arguments...
  • 实例(除了基本类型的字面量创建的值)
  • prototype的值
  • 函数

原型和原型链的定义

  1. 所有的\color{#FF0000}{函数数据类型}都天生自带一个属性:prototype(原型),这个属性的值是一个对象,浏览器会默认给它开辟一个堆内存。
  2. 在浏览器给prototype开辟的堆内存中有一个天生自带的属性constructor,这个属性存储的值是当前函数本身,prototype里的属性和方法对于实例是公有的方法,对于原型自己是私有方法。
    3.每一个\color{#FF0000}{对象}都有一个__proto__的属性,这个属性指向当前实例\color{#FF0000}{所属类}prototype,(如果不能确定它是谁的实例,都是Object的实例)
    原型和原型链机制

    在这里ary既是Array的实例,
    因为它能通过_proto_找到Arrayprototype,同样根据原型链的查找机制,Array_proto_指向了Obejctprototype,所以ary
    也是Obejct的实例。也就是说,如何判断某个实例是不是属于某个类,就判断这个实例的原型链上是不是有这个类。
    原型链是一种基于_proto_向上查找的机制,当我们操作实例的某个属性或者方法的时候,首先找自己空间中私有的属性或者方法 如果找到了则结束查找,使用自己私有的即可,没找到则基于_proto_找所属类的prototype,如果找到就用这个公有的,如果没找到就基于原型上的_proto_继续向上查找,一直找到Obejct的原型为止,如果再没有,操作的原型或者方法不存在。
    例如:
//34.原型链和原型链的查找机制
function Fn() {
    var n = 100;
    this.AA = function () {
        console.log(`AA[私有]`);
    };
    this.BB = function () {
        console.log(`BB[私有]`);
    };
}
Fn.prototype.AA = function () {
    console.log(`AA[公]`);
};

var f1 = new Fn;
var f2 = new Fn;

console.log(f1.n);

原型修改

如果我们是在原型上增加或者修改属性或者方法这不会修改原型的constructor

function Fn() {
  ...
}
fun.prototype.a = function () {
       ...
}
fun.prototype.b = function () {
       ...
}

原型重定向

在实际项目基于面向对象开发的时候(构造原型设计模式),我们根据需要,很多时候会重定向类的原型(让类的原型指向自己开辟的堆内存)
如果自己进行原型的重定向,需要注意以下问题:

  • 自己开辟的堆内存中没有constructor属性,导致类的原型构造函数缺失
  • 当原型重定向后,如果原来的原型堆内存没有被重定向之前创建的实例所指向(重定向之前的实例指向原有原型),那么浏览器默认开辟的那个原型堆内存会被释放掉,如果之前已经存储了一些方法或者属性,这些东西都会丢失(所以:内置类的原型不允许重定向到自己开辟的堆内存,因为内置类原型上自带很多属性方法,重定向后都没了,这样是不被允许的)


    内置类原型不能重定向

    内置类原型不能重定向

    当我们需要给类的原型批量设置属性和方法的时候,一般都是让原型重定向到自己创建的对象中。

function Fn() {
    ...
}
Fn.prototype = {
    constructor: Fn,  //如果不写这个,默认根据原型链查找会指向Object
    aa: function () {

    }
}
//41.课件7&练习题讲解[15]-构造函数和原型链的运行机制
1.function Fn() {
2.    this.x = 100;
3.    this.y = 200;
4.    this.getX = function () {
5.        console.log(this.x);
6.    }
7.}
8.Fn.prototype.getX = function () {
9.    console.log(this.x);
10.};
11.Fn.prototype.getY = function () {
12.    console.log(this.y);
13.};
14.var f1 = new Fn;
15.var f2 = new Fn;
16.console.log(f1.getX === f2.getX);
17.console.log(f1.getY === f2.getY);
18.console.log(f1.__proto__.getY === Fn.prototype.getY);
19.console.log(f1.__proto__.getX === f2.getX);
20.console.log(f1.getX === Fn.prototype.getX);
21.console.log(f1.constructor);
22.console.log(Fn.prototype.__proto__.constructor);
23.f1.getX();
24.f1.__proto__.getX();
25.f2.getY();
26.Fn.prototype.getY();
图解

答案
//44.课件10&练习题讲解[18]-关于原型重定向问题.flv
function fun() {
    this.a = 0;
    this.b = function () {
        alert(this.a);
    }
}

fun.prototype = {
    b: function () {
        this.a = 20;
        alert(this.a);
    },
    c: function () {
        this.a = 30;
        alert(this.a)
    }
};
var my_fun = new fun();
my_fun.b();
my_fun.c();
图解

没有在_proto_设置的是私有属性

私有公有属性是相对于实例或者原型来说的
//45.课件11&练习题讲解[19]-关于原型重定向问题综合练习
function Fn() {
    var n = 10;
    this.m = 20;
    this.aa = function () {console.log(this.m);}
}
Fn.prototype.bb = function () {console.log(this.n);};
var f1=new Fn;
Fn.prototype={
    aa:function(){console.log(this.m+10);}
};
var f2=new Fn;
console.log(f1.constructor);
console.log(f2.constructor);
f1.bb();
f1.aa();
// f2.bb();
f2.aa();
f2.__proto__.aa();
答案:
console.log(f1.constructor);//Fn
console.log(f2.constructor);//Object
f1.bb();//undefined
f1.aa();//20
f2.bb();//报错:f2.bb is not a function
f2.aa();//20
f2.__proto__.aa();//NaN
图解
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,635评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,628评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,971评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,986评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,006评论 6 394
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,784评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,475评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,364评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,860评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,008评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,152评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,829评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,490评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,035评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,156评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,428评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,127评论 2 356