1、首先我们先来看一张图

prototype

每个函数都有一个 prototype 属性
每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型"继承"属性。

demo:

function Person() {

}
// 虽然写在注释里,但是你要注意:
// prototype是函数才会有的属性
Person.prototype.name = 'Kevin';
var person1 = new Person();
var person2 = new Person();
console.log(person1.name) // Kevin
console.log(person2.name) // Kevin

构造函数Person可以通过prototype属性访问到它的原型对象

function Person() {

}
// 虽然写在注释里,但是你要注意:
// prototype是函数才会有的属性
console.log(Person.prototype)

通过构造函数Preson实例化出来的person可以通过__proto__属性访问到Man的原型对象

function Person() {

}
var person = new Person();
console.log(person.__proto__ === Person.prototype); // true

Person的原型对象可以通过constructor(构造器)属性访问其关联的构造函数

function Person() {

}
console.log(Person === Person.prototype.constructor); // true

so 我们可以通过三种方式来访问原型对象

1.构造函数.prototype

2.实例对象.__proto__

3.object.getPrototypeOf(实例对象)


原型链的访问规则

对象在访问属性或方法时,先检查自己的实例,如果存在就直接使用。如果不存在那么就去原型对象上去找,存在就直接使用,如果没有就顺着原型链一直往上查找,找到即使用,找不到就重复该过程直到原型链的顶端,如果还没有找到相应的属性或方法,就返回undefined,报错

function Person() {

}

Person.prototype.name = 'Kevin';

var person = new Person();

person.name = 'Daisy';
console.log(person.name) // Daisy delete person.name;
console.log(person.name) // Kevin

在这个例子中,我们给实例对象 person 添加了 name 属性,当我们打印 person.name 的时候,结果自然为 Daisy。

但是当我们删除了 person 的 name 属性时,读取 person.name,从 person 对象中找不到 name 属性就会从 person 的原型也就是 person.proto ,也就是 Person.prototype中查找,幸运的是我们找到了 name 属性,结果为 Kevin。

 

原型与原型(看头部大图理解)

var obj = new Object();
obj.name = 'Kevin'
console.log(obj.name) // Kevin

console.log(Object.prototype.__proto__ === null) // true

JavaScript 默认并不会复制对象的属性,相反,JavaScript 只是在两个对象之间创建一个关联,这样,一个对象就可以通过委托访问另一个对象的属性和函数,所以与其叫继承,委托的说法反而更准确些
 

三种检验方法

Object.getPrototypeOf方法用于获取指定实例对象的原型对象。

 //01 声明构造函数F
function F() {} //02 使用构造函数F获取实例对象f
var f = new F(); //03 测试getPrototypeOf方法的使用
console.log(Object.getPrototypeOf(f)); //打印的结果为一个对象,该对象是F相关联的原型对象
console.log(Object.getPrototypeOf(f) === F.prototype); //true
console.log(Object.getPrototypeOf(f) === f.__proto__); //true

isPrototypeOf方法用于检查某对象是否在指定对象的原型链中。

function Demo(){}
var demo = new Demo(); console.log(Demo.prototype.isPrototypeOf(demo)); // true
console.log(Object.prototype.isPrototypeOf(demo)); //true
console.log(Object.prototype === person.__proto__.__proto__) //true

instanceof运算符的作用跟isPrototypeOf方法类似,左操作数是待检测的实例对象,右操作数是用于检测的构造函数。如果右操作数指定构造函数的原型对象在左操作数实例对象的原型链上面,则返回结果true,否则返回结果false。

// 1 声明构造函数Demo
function Demo(){};
// 2 获取实例化对象demo
var demo = new Demo();
// 3 使用isPrototypeOf
console.log(demo instanceof Demo); //true
console.log(demo instanceof Object); //true
// 4 Object构造函数的原型对象在Function这个实例对象的原型链中
console.log(Function instanceof Object); //true
console.log(Object.prototype === Function.__proto__.__proto__); //true
// 5 Function构造函数的原型对象在Object这个实例对象的原型链中
console.log(Object instanceof Function); //true
console.log(Function.prototype === Object.__proto__); //true
 

注意:不要错误的认为instanceof检查的是该实例对象是否从当前构造函数实例化创建的,其实它检查的是实例对象是否从当前指定构造函数的原型对象继承属性。

 //01 声明构造函数Person
function Person() {} //02 获取实例化对象p
var p1 = new Person(); //03 测试isPrototypeOf的使用
console.log(p1 instanceof Person); //true //04 替换Person默认的原型对象
Person.prototype = {
constructor:Person,
showInfo:function () {
console.log("xxx");
}
}; //05 重置了构造函数原型对象之后,因为Person
console.log(p1 instanceof Person); //false //06 在Person构造函数重置了原型对象后重新创建实例化对象
var p2 = new Person();
console.log(p2 instanceof Person); //true //==> 建议开发中,总是先设置构造函数的原型对象,之后在创建实例化对象

原型链相关的继承

原型式继承基本写法

 //01 提供超类型|父类型构造函数
function SuperClass() {} //02 设置父类型的原型属性和原型方法
SuperClass.prototype.info = 'SuperClass的信息';
SuperClass.prototype.showInfo = function () {
console.log(this.info);
}; //03 提供子类型
function SubClass() {} //04 设置继承(原型对象继承)
SubClass.prototype = SuperClass.prototype;
SubClass.prototype.constructor = SubClass; var sub = new SubClass();
console.log(sub.info); //SuperClass的信息
sub.showInfo(); //SuperClass的信息

原型链继承

实现思想

核心:把父类的实例对象设置为子类的原型对象 SubClass.prototype = new SuperClass();
问题:无法为父构造函数(SuperClass)传递参数

//01 提供超类型|父类型
function SuperClass() {
this.name = 'SuperClass的名称';
this.showName = function () {
console.log(this.name);
}
} //02 设置父类型的原型属性和原型方法
SuperClass.prototype.info = 'SuperClass的信息';
SuperClass.prototype.showInfo = function () {
console.log(this.info);
}; //03 提供子类型
function SubClass() {} //04 设置继承(原型对象继承)
var sup = new SuperClass();
SubClass.prototype = sup;
SubClass.prototype.constructor = SubClass; var sub = new SubClass();
console.log(sub.name); //SuperClass的名称
console.log(sub.info); //SuperClass的信息
sub.showInfo(); //SuperClass的信息
sub.showName(); //SuperClass的名称

组合继承

实现思想

① 使用原型链实现对原型属性和方法的继承
② 通过伪造(冒充)构造函数来实现对实例成员的继承,并且解决了父构造函数传参问题

 //01 提供超类型|父类型
function SuperClass(name) {
this.name = name;
this.showName = function () {
console.log(this.name);
}
} //02 设置父类型的原型属性和原型方法
SuperClass.prototype.info = 'SuperClass的信息';
SuperClass.prototype.showInfo = function () {
console.log(this.info);
}; //03 提供子类型
function SubClass(name) {
SuperClass.call(this,name);
} //(1)获取父构造函数的实例成员 Person.call(this,name);
//(2)获取父构造函数的原型成员 SubClass.prototype = SuperClass.prototype;
SubClass.prototype = SuperClass.prototype;
SubClass.prototype.constructor = SubClass; var sub_one = new SubClass("zhangsan");
var sub_two = new SubClass("lisi");
console.log(sub_one);
console.log(sub_two);

JS中关于原型对象与原型链的理解!的更多相关文章

  1. Js中找任意对象的原型方法及改造原型

    Java中有运行时类型识别,js可以很方便的模仿这个特性,因为所有js对象都有一个属性constructor(构造器),表示这个对象的构造方法,原型与构造方法同名,所以可以通过这儿知道任意对象的原型名 ...

  2. 三张图较为好理解JavaScript的原型对象与原型链

    最近从网上看到别人详细得讲解了js的原型对象和原型链,看完感觉是看得最清晰的一个,于是,摘录到自己博客里 对于新人来说,JavaScript的原型是一个很让人头疼的事情,一来prototype容易与_ ...

  3. 还在问什么是JavaScript构造函数、实例、原型对象以及原型链?看完这篇你就懂

    1概述 ES6, 全称 ECMAScript 6.0 ,2015.06 发版.在ES6之前,对象不是基于类创建的,而是用一种称为构造函数的特殊函数来定义对象和它们的特征. 2构造函数 构造函数是一种特 ...

  4. jacascript 构造函数、原型对象和原型链

    前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! 先梳理一下定义: 我们通常认为 object 是普通对象,function 是函数对象: Function ...

  5. 说一说js中__proto__和prototype以及原型继承的那些事

    在面试中遇到过,问js如何实现继承,其实最好的方式就是构造函数+原型,今天在讨论中,发现自己以前理解上的一些误区,特地写出来,最近都比较忙,等手上的项目做完,可以来做个总结. 先说我以前没有认识到位的 ...

  6. 【javascript】对原型对象、原型链的理解

    原型对象,原型链这些知识属于基础类知识.但是平时开发过程中也很少用到. 看网上的意思,原型链用于es5开发场景下的继承.es6有了类语法糖之后,就自带继承了. 通过理解,个人画了一张原型链解构的关系图 ...

  7. javascript原型对象与原型链

    在javascript中,当系统加载构造函授后 ,会自动在内存中增加一个对象,这个对象就是原型对象.构造函数和原型对象在内存中表现为相互独立,但两者之间还存在联系,构造函数的prototype是原型对 ...

  8. JavaScript基础之原型对象和原型链

    原型对象 原型对象简单来说就是函数的原型所指向的对象.前面说原型的时候,说了Object.prototype所指对象就是Object(函数)的原型对象.在每个函数的原型对象中,默认会有construc ...

  9. js中关于Blob对象的介绍与使用

    js中关于Blob对象的介绍与使用   blob对象介绍 一个 Blob对象表示一个不可变的, 原始数据的类似文件对象.Blob表示的数据不一定是一个JavaScript原生格式 blob对象本质上是 ...

  10. 对ES6中类class以及实例对象、原型对象、原型链之间关系的详细总结

    1. 类 ES6 中新增加了类的概念,可以使用 class 关键字声明一个类,之后用这个类来实例化对象.即类的用途:实例化对象. // 创建一个Person类 class Person { } // ...

随机推荐

  1. lightgbm与贷款违约预测项目

    lightgbm histogram算法 将连续的浮点值离散成k个离散值,构造宽度为k的histogram leaf-wise生长策略 每次在所有叶子中找到分裂增益最大的一个叶子,一般也是数据量最大的 ...

  2. UnsupportedOperationException异常

    看看下面的例子,这样输出什么呢? public class test { public static void main(String[] args) { String arr = "ab, ...

  3. Ribbon负载均衡的实现流程简要分析

    SpringCloud中使用Netflix方案做分布式时,只需要在RestTemplate的bean定义上加一个注解@LoadBalanced,无需做其它任何操作就可以开启负载均衡,怎么做到的呢? 不 ...

  4. Matlab|multcompare文档

    multcompare Syntax c = multcompare(stats) c = multcompare(stats,Name,Value) [c,m] = multcompare(___) ...

  5. django_设计模式和模板层

    一.django的设计模式 1.传统MVC设计模式 (1)MVC(Model-View-Controller,模型-视图-控制器)模式. M--模型层,主要用于对数据库的封装: V--视图层,用于向用 ...

  6. CF823div2B

    cf823div2B 题目链接 题目大意 多组测试数据,有\(n\)个点在数轴上,他们想要集会,每个点到目标点\(y\)的时间为$$t_i+|x_i-y|$$ 试求所有点到\(y\)中最长时间的最小值 ...

  7. CATIA的后处理

    同其他的cam软件一样,catia可以使用配置好的后处理文件输出相应的G代码文件, 也可以输出相应的刀位文件. 下图中的1选择的是后处理文件:下图2种设置的是输出刀位文件的格式. 输出G代码: 选择[ ...

  8. SQL的分类

    DDL: 数据定义语言,用来定义数据库对象(数据表,表 ,字段) : DML:数据操作语言,用来对数据库表中的数据进行增删改 : DQL:数据库查询语言,用来查询数据库中的表的记录 DCL:数据控制语 ...

  9. 常用的typedef 定义

    今天开始学习VC++基础,系统编程栏目下都是WinAPI和MFC的内容,此为浏览博客园时学习的一篇文章,觉得很实用,拿来做笔记. 出处见最底部. 三行代码:     typedef char CHAR ...

  10. FIR滤波器的设计

    FIR数字滤波器的设计 线性相位FIR滤波器的特点 单位冲激响应:\(h(n),0\leq n\leq N-1\) 系统函数:\(H(z)=\sum_{n=0}^{N-1}h(n)z^{-n}\) 零 ...