原型链

原型

什么是原型

每个函数都有一个原型对象(prototype),它是一个属性也是一个指针,指向一个对象。
当所有对象有一共有的属性时,就可以用prototype添加,不用一个一个的重复添加。

Person.prototype.name = "Xiaoming";
Person.prototype.age = 18;
function Person(){
}
var person1 = new Person();

原型的属性

  • constructor:创建了构造函数后,系统默认其对象有constructor属性。这个属性指向原函数。
Person.prototype.constructor == Person;

相应的,在每一个使用构造函数新建的实例中,也存在一个指针,指向构造函数的原型对象。这个指针可以为[[prototype]]或__proto__。

  • isPrototypeOf:确定传入的对象的原型是否是当前的对象。
var result = Person.prototype.isprototypeOf(person1);           //true
  • getPrototypeOf:ES5新添加的属性,可以返回实例对象的原型。
var result = Object.getPrototypeOf(person1);                 //Person.prototype

原型中值的更改

虽然我们能用对象实例去访问对象原型中的值,但是不能使用实例去改变原型中已有的属性和值。

Person.prototype.name = "Xiaoming";
        Person.prototype.age = 18;
        function Person(){ 
        }
        var person1 = new Person();
        var person2 = new Person();

        person1.name = 'Xiaohua';
        console.log(person1.name);

当像这样使用实例强制改变原型中的值时,原型中的值会被覆盖,
这种情况被称为属性遮蔽 (property shadowing)
此时再访问 person1 . name,返回值为‘Xiaohua’;
原有的原型值没有并没有改变。
当delete person1.name时,再次访问person1 . name,返回为‘Xiaoming’;

原型的重写

关于创建原型实例和修改原型的问题。

  1. 当先创建实例,后添加属性值时:
function Person(){ 
        }
var person1 = new Person();
    Person.prototype.name = 'Xiaoming';
    console.log(person1.name);                        //'Xiaoming'

尽管原型赋值在后,但是由于实例与原型松散的连接,所以在寻找person1.name中后从实例找到原型中。所以可以随时给原型添加属性和方法。
2. 当改变重写原型对象时。

function Person(){ 
        }
var person1 = new Person();
Person.prototype = {
            name : 'Xiaoming',          //上面讲到当使用这种方法创建原型时,
            age : 18,                   //会改变原型constructor的指向
            job : 'student'
}
console.log(person1.name);           //因此现在找不到person1.name,返回undefined

原型链

Grand.prototype.lastName = 'Xiaoming';
function Grand(){
}
var grand = new Grand();
Father.prototype = grand;
function Father(){
    this.name = 'Xiaoqiang';
} 
var father = new Father();
son.prototype = father;
function Son(){
    this.hobbit = 'havana';
}
var son = new Son();

由上可以看出原型链的实现方法。
此时原型对象包含一个指向另一个原型的指针,则另一个原型中也包含着一个指向另一个构造函数的指针。当另一个原型又是另一个原型的实例,如此层层递进,就构成原型与实例的链条。
而原型链的终端则是Object.prototype。
简而言之,上面的代码中:Son继承了Father,Father继承了Grand,Grand继承了Object。

  • 虽然绝大多数对象都继承自Object.prototype,但是还是例外。
  • 我们可以构建出不继承自Object的对象
  • 使用Object.create(null)即可

谨慎定义

在原型链中定义方法时,不能使用对象字面量创建原型方法。

function Father(){
    this.name = 'Xiaoming';
} 
var father = new Father();
function Son(){
    this.hobbit = 'havana';
}
son.prototype = father;
//这时添加方法,会切断son和father之间的连接,原型链被切断了
son.prototype = {
    action : function(){
        return 'walk';
    }
}
var son = new Son();

原型链的问题

含有引用值的原型属性会被所有实例共享,这就造成了原型链的缺陷。

function Father(){
    this.TshirtColors = ['red','blue','yellow'];
} 
var father = new Father();
function Son(){
    this.hobbit = 'havana';
}
son.prototype = father;
var son1 = new Son();
var son2 = new Son();
son1.TshirtColors.push('black');
alert(son1.TshirtColors);   //'red','blue','yelllow','black'
alert(son2.TshirtColors);   //'red','blue','yelllow','black'
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
在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、付费专栏及课程。

余额充值