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. python+pytesseract识别图片文字

    此文只介绍一下python+pytesseract识别一些简单图片的数字,字母和汉字.如图1 import pytesseract from PIL import Image,ImageEnhance ...

  2. vue父子件,子件页面table数据列按条件显示不同的内容

    需求:在父件中点击按钮.子件弹框中,table列根据条件显示不同的数据 实现思路:点击按钮,执行不同的方法,方法中参数值不同,从而展示不同的columns. 父件按钮如下图: 父件中导入子件需要注意的 ...

  3. javase我的笔记

    学习java编程 |--需要遵循其语法规范 |--在其开发环境下编程 准备开发java环境 |--安装jdk |--配置jdk jdk:含义是java提供的一套开发工具,包含jre\编译器等 |--编 ...

  4. c++ 在项目中创建DLL,并调用

    创建DLL分为两种方法,先介绍第一种 一.创建DLL (1) // dll.h #pragma once //dll.h #ifndef DLL_H_ #define DLL_H_ void prin ...

  5. idea :不支持发行版本11问题

    1.因为我是导入的其他人的项目来进行修改的,所以遇到了这个问题 2. 3. 4.

  6. 使用idea从零编写SpringCloud项目-Ribbo

    git:https://github.com/bmdcheng/product_server git:https://github.com/bmdcheng/order_server 1.需要创建两个 ...

  7. 使用Microsoft Network Monitor 抓包分析文件上传

    Microsoft 自己提供了一个官方的抓包工具,可以比较方便的在windows平台抓包,并可以提供协议关键字正则.安装包位置:\\192.168.10.248\public\ghw\tools\MN ...

  8. Day03_Class01

    用户交互Scanner Scanner对象 基本语法 Scanner sc = new Scanner(System.in); 通过Scanner类的next()与nextLine()方法获取输入的字 ...

  9. python发布定时任务(schedule模块)

    最近公司开始让在自己开发的软件上写日志,有几次下班了都忘了写,好几次都是给领导发邮件,说明一下自己没有写日志这件事,很麻烦.但是我一想我每天都要写,岂不是很麻烦,想想自己之前有爬虫经验,为什么自己不写 ...

  10. Angular 管道和路由

    管道pipe: 要在HTML模板中指定值转换,请使用管道运算符(|). {{interpolated_value | pipe_name}} 您可以链接管道,发送一个管道功能的输出以被另一个管道功能转 ...