原型链

概念:在javascript中,每个对象都有一个指向它的原型(prototype)对象的内部链接。每个原型对象又有自己的原型,直到某个对象的原型为null为止,组成这条链的最后一环,构造函数里有一个prototype对象,只要修改了prototype对象,就会同时影响到两个实例对象

一、为什么需要原型

用构造函数生成实例对象,有一个缺点,无法共享属性和方法。每一个实例对象,都有自己的属性和方法的副本。这不仅无法做到数据共享,也是极大的资源浪费
  
考虑到这一点,设计js作者决定为构造函数设置一个prototype属性。这个属性包含一个对象(以下简称"prototype对象"),所有实例对象需要共享的属性和方法,都放在这个对象里面;那些不需要共享的属性和方法,就放在构造函数里面。

实例对象一旦创建,将自动引用prototype对象的属性和方法。也就是说,实例对象的属性和方法,分成两种,一种是本地的,另一种是引用的。

二、原型(prototype)

概念:每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。

三、原型的继承方式(两类5种)

  1. 原型链继承
function Show(){
this.name="run";
}

function Run(){
this.age="20"; //Run继承了Show,通过原型,形成链条
}
Run.prototype=new Show();
var show=new Run();
alert(show.name)//结果:run
  1. 构造函数继承(对象冒充继承)

为了解决引用共享和超类型无法传参的问题,我们采用一种叫借用构造函数的技术,或
者成为对象冒充(伪造对象、经典继承)的技术来解决这两种问题

function Box(age){
this.name=['Lee','Jack','Hello']
this.age=age;
}
function Desk(age){
Box.call(this,age); //对象冒充,给超类型传参
}
var desk = new Desk(200);
alert(desk.age);//200
alert(desk.name);//['Lee','Jack','Hello']
desk.name.push('AAA'); //添加的新数据,只给 desk
alert(desk.name)//['Lee','Jack','Hello','AAA']
  1. 组合继承(原型链继承+构造函数继承)

借用构造函数虽然解决了刚才两种问题, 但没有原型, 复用则无从谈起。 所以, 我们需
要原型链+借用构造函数的模式,这种模式成为组合继承。

function Box(age) {
this.name = ['Lee', 'Jack', 'Hello']
this.age = age;
}
Box.prototype.run = function () {
return this.name + this.age;
};
function Desk(age) {
Box.call(this, age); //对象冒充
}
Desk.prototype = new Box(); //原型链继承
var desk = new Desk(100);
alert(desk.run());
  1. 原型式继承

这种继承借助原型并基于已有的对象创建新对象,
同时还不必因此创建自定义类型

function obj(o) { //传递一个字面量函数
function F() {} //创建一个构造函数
F.prototype = o; //把字面量函数赋值给构造函数的原型
return new F(); //最终返回出实例化的构造函数
}
var box = { //字面量对象
name : 'Lee',
arr : ['哥哥','妹妹','姐姐']
};
var box1 = obj(box); //传递
alert(box1.name);
box1.name = 'Jack';
alert(box1.name);
alert(box1.arr);
box1.arr.push('父母');
alert(box1.arr);
var box2 = obj(box); //传递
alert(box2.name);
alert(box2.arr); //引用类型共享了
  1. 寄生组合式继承

寄生组合式继承解决了两次调用的问题,组合式继承就会有两次调用的情况

基本模型如下:

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

function inheritPrototype(subType, superType) {
    var prototype = object(superType.prototype);  //创建对象
    prototype.constructor = subType;              //增强对象
    subType.prototype = prototype;                //指定对象
}
var num = new Number(1);
num.__proto__ === Number.prototype; // true

Number.__proto__ === Object.prototype // false
String.__proto__ === Object.prototype // false
Boolean.__proto__ === Object.prototype // false
那么它们的__proto__属性又是指向哪里?这里要提出一个特殊的对象Function。
Number, String, Boolean既是对象,同时也是方法或者叫函数,在这种情况下,我们认为它们的__proto__属性,指向的的是Function.prototype。因为它们是由Function对象构造出来的,如同num, str, boo分别由Number, String, Boolean对象构造出来一样。而不例外的是,Object和Function本身,也是由Function构造出来的。
Number.__proto__ === Function.prototype // true
String.__proto__ === Function.prototype // true
Boolean.__proto__ === Function.prototype // true

Object.__proto__ === Function.prototype // true
Function.__proto__ === Function.prototype // true
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在JavaScript中,每个对象都有一个隐藏的 `__proto__` 属性,它指向该对象的原型。原型是一个普通的对象,它包含了共享属性和方法。当我们访问一个对象的属性或方法时,JavaScript引擎会首先在该对象本身查找,如果找不到,则会沿着原型链向上查找,直到找到该属性或方法,或者到达原型链的顶端(Object.prototype)。这个原型链的过程就是通过 `__proto__` 属性来实现的。 例如,当我们创建一个实例对象 `teacher` 时,如果 `teacher` 对象本身没有 `teach()` 方法,JavaScript引擎会通过对象的 `__proto__` 属性查找到 `Teacher.prototype` 的显式原型上,如果 `Teacher.prototype` 仍然没有该方法,它会继续沿着 `Teacher.prototype.__proto__` 找到 `Person.prototype`,直到找到 `teach()` 方法并执行。这样就形成了一个原型链。 同时,可以注意到 `Object.prototype.__proto__` 的值为 `null`,即 `Object.prototype` 没有原型。所以在原型链中,当找到顶层原型还没有属性时,就会返回 `undefined`。 需要注意的是, `__proto__` 是一个非标准的属性,实际开发中不应该直接使用它。它只是内部指向原型对象 `prototype` 的一个指示器,我们应该使用 `Object.getPrototypeOf()` 或 `Object.setPrototypeOf()` 来访问和设置对象的原型。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [JS:原型和原型链](https://blog.csdn.net/elevenhope/article/details/122882582)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [JavaScript原型链(重要)](https://blog.csdn.net/liyuchenii/article/details/125957625)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值