JavaScript -- 原型与原型链

news/2024/7/19 15:28:40 标签: javascript, 前端, js, 原型与原型链, prototype

根据视频进行整理
【https://www.bilibili.com/video/BV14s411E7qf?p=15】
视频对应资源(百度网盘):
链接:【https://pan.baidu.com/s/1q9LnJcRt5alTV67gUDqpnw】
提取码:1234


JavaScript -- 原型与原型链

  • 1 原型与原型链
    • 1.1 原型 prototype
    • 1.2 显示原型与隐式原型
      • 小结
    • 1.3 原型链
    • 1.4 原型链_属性问题
    • 1.5 instanceof
    • 1.6 面试题


1 原型与原型链

prototype_12">1.1 原型 prototype

1、每个函数都有一个prototype属性

javascript">    // 每个函数都有一个prototype属性
    function myfunc() {

    }
    console.log(myfunc.prototype)
    console.log(Date.prototype)

在这里插入图片描述

2、函数prototype属性,其类型为object

javascript">    // 每个函数都有一个prototype属性
    function myfunc() {

    }
    console.log( typeof myfunc.prototype)
    console.log( typeof Date.prototype)

在这里插入图片描述

3、函数prototype属性默认指向一个Object空对象(即称为: 原型对象)

Object空对象:
是指该对象上没有我们自定义的属性

javascript">    console.dir( myfunc.prototype)
    console.log(new Object())

在这里插入图片描述

4、函数prototype属性指向的对象为原型对象

5、原型对象中有一个属性constructor, 它指向函数对象

javascript">    console.log(myfunc.prototype.constructor === myfunc)
    console.log(Date.prototype.constructor === Date)

在这里插入图片描述
在这里插入图片描述

6、可以通过prototype给原型对象添加属性(一般是方法)

作用:
可以使函数的所有实例对象都自动拥有原型中的属性(方法)

通过prototype给原型对象添加属性,添加的属性供实例对象使用

javascript">      // 构造函数
      function Fun() {}
      // 向函数的原型对象上添加属性
      Fun.prototype.test = function() {
        console.log('Fun.prototype.test')
      }
      // 实例化对象
      const fun1 = new Fun()
      console.log(fun1)
      fun1.test()

在这里插入图片描述

1.2 显示原型与隐式原型

1、每个函数function都有一个prototype,即显式原型(属性)

2、每个实例对象都有一个__proto__,可称为隐式原型(属性)

javascript">    // 每个函数function都有一个prototype,即显式原型(属性)
    function Fun() {}
    console.log(Fun.prototype)
    // 每个实例对象都有一个__proto__,可称为隐式原型(属性)
    var fun = new Fun()
    console.log(fun.__proto__)

在这里插入图片描述

3、实例化出来的对象的隐式原型的值为其对应构造函数的显式原型的值

显示原型属性指向一个没有我们自定义属性的对象,隐式原型属性指向显示原型属性指向的对象。

在这里插入图片描述

javascript">    // 实例化出来的对象的隐式原型的值为其对应构造函数的显式原型的值
    console.log(fun.__proto__ === Fun.prototype)

在这里插入图片描述

在这里插入图片描述

javascript">    // 通过函数的prototype给原型添加属性
    Fun.prototype.test = function() {
      console.log('test')
    }
    // 实例对象调用添加的属性
    fun.test()

函数向原型中添加属性通过显示原型属性
实例对象使用新添加的属性通过隐式原型属性进行查找
在这里插入图片描述

输出结果:
在这里插入图片描述

小结

  • 函数的prototype属性: 在定义函数时自动添加的, 默认值是一个没有自定义属性的Object对象
  • 对象的__proto__属性: 创建对象时自动添加的, 默认值为构造函数的prototype属性值
  • 程序员能直接操作显式原型, 但不要直接操作隐式原型(ES6之前)

1.3 原型链

javascript">      function Fn() {
        this.test1 = function () {
          console.log('test1()')
        }
      }
      Fn.prototype.test2 = function () {
        console.log('test2()')
      }

      var fn = new Fn()

      fn.test1()
      fn.test2()
      console.log(fn.toString())
      fn.test3()

在这里插入图片描述

访问一个对象的属性时:

  • 先在自身属性中查找,找到返回
  • 如果没有, 再沿着__proto__这条链向上查找, 找到返回
  • 如果最终没找到, 返回undefined

原型链的尽头为Object的原型对象。

原型链:

  • 本质上是隐式原型链
  • 作用: 查找对象的属性(方法)

fn.test3() 会在对象的属性和其原型链中查找
test3() 函数变量,会在作用域链中进行查找

所有函数的隐式原型都相等,因为所有函数都是函数构造器函数Function()的实例对象,所以所有函数对象的隐式原型属性都相等,都等于函数构造器函数Function()的显示原型属性

补充:
1、函数的显示原型指向的对象默认是空Object实例对象(但Object函数的原型对象不满足)
空:对于程序员来说,没有放任何的属性方法到对象中
Object的显示原型对象为null
Object函数:对象的构造函数 Object()

javascript">      console.log(Fn.prototype instanceof Object) // true
      // Object的显示原型对象再向上就没了
      console.log(Object.prototype instanceof Object) // false
      console.log(Function.prototype instanceof Object) // true

在这里插入图片描述

2.、所有函数都是Function的实例(包含Function)

javascript">      // 自身的实例,隐式原型的指向和现实原型的指向相等
      console.log(Function.__proto__ === Function.prototype)

在这里插入图片描述

3、Object的原型对象是原型链尽头

javascript">console.log(Object.prototype.__proto__) // null

在这里插入图片描述

1.4 原型链_属性问题

1、读取对象的属性值时: 会自动到原型链中查找
2、设置对象的属性值时: 不会查找原型链, 如果当前对象中没有此属性, 直接添加此属性并设置其值

javascript">      function Fn() {}
      // 在原型上设置一个属性 a 值为 xxx
      Fn.prototype.a = 'xxx'
      // Fn实例化对象 fn1
      var fn1 = new Fn()
      console.log(fn1.a, fn1)
      // Fn实例化对象 fn2
      var fn2 = new Fn()
      // 给 fn2 对象设置属性 a 值为 yyy
      // fn2 中没有 a 属性,会给 fn2 添加一个 a 属性
      fn2.a = 'yyy'
      console.log(fn1.a, fn2.a, fn2)

在这里插入图片描述

3、方法一般定义在原型中, 属性一般通过构造函数定义在对象本身上

对象的属性一般在构造函数中进行设置

javascript">  function Person(name, age) {
    this.name = name
    this.age = age
  }
  Person.prototype.setName = function (name) {
    this.name = name
  }

属性在自身身上(每个对象的属性值会有所不同),方法在原型上

javascript">  var p1 = new Person('Tom', 12)
  p1.setName('Bob')
  console.log(p1)
  
  var p2 = new Person('Jack', 12)
  p2.setName('Cat')
  console.log(p2)

在这里插入图片描述

1.5 instanceof

instanceof是如何判断的?
表达式: A instanceof B
如果B函数的显式原型对象在A对象的原型链上, 返回true, 否则返回false

javascript">  // Object这里为构造器函数,是Function的一个实例对象
  // Object => Object.__proto__ === Function.prototype
  console.log(Object instanceof Function) // true
  // Object作为对象的显示原型属性为Object.prototype
  // Object作为构造函数是Function的实例对象,Function是Object的实例(函数是特殊的对象)
  // Object => Object.__proto__ === Function.prototype => Object
  console.log(Object instanceof Object) // true
  console.log(Function instanceof Function) // true
  // 函数是特殊的对象
  console.log(Function instanceof Object) // true

  function Foo() {}
  // 函数类型的数据对象
  // Foo.prototype
  // Object.__proto__ => Function.prototype => Object.prototype 
  console.log(Object instanceof  Foo) // false

1.6 面试题

javascript">  function A () {

  }
  A.prototype.n = 1

  var b = new A()

  A.prototype = {
    n: 2,
    m: 3
  }

  var c = new A()
  console.log(b.n, b.m, c.n, c.m)

在这里插入图片描述

javascript">  function F (){}
  Object.prototype.a = function(){
    console.log('a()')
  }
  Function.prototype.b = function(){
    console.log('b()')
  }
  
  var f = new F()
  // f是一个对象
  // f => Object => Object.prototype
  // F是一个函数,Function的实例
  // F => Function => Object => Object.prototype
  f.a()
  // f.b() // 不存在,会报错
  F.a()
  F.b()
  // console.log(f)
  // console.log(Object.prototype)
  // console.log(Function.prototype)

在这里插入图片描述


http://www.niftyadmin.cn/n/563672.html

相关文章

学什么技术好?

现在不管是大专生仍是本科生作业越来越困难,没有自己具有优势的技能才能很难从其中脱颖而出,那么究竟学些什么技能好呢?   以个人见解来说,现在最好的技能,和最多的时机都是在互联网上,如果想学技能的话我…

vscode是什么(vscode干嘛用的)

vscode是什么   接触VSCode不太长。   但是我觉得我越来越喜欢它,所以我想写些关于它的东西。vscode   首先介绍一下这东西是什么。   当然,这是由M$开发和开源的轻量级IDE,可以免费使用。我这样定义。   它和VisualStudio之间的区…

计算机组成原理(微课版) -- 第一章 -- 计算机系统概述

第一章根据视频【计算机组成原理(哈工大刘宏伟)135讲(全)高清】(P2 - P10)和书本【计算机组成原理(微课版) 】进行整理 文章目录1.1 计算机发展历程1.2 计算机系统的组成存储器运算器控制器输入输出设备1.3…

PHP 实现中文分词搜索功能

中文分词介绍   众所周知,英语是基于单词的,单词和单词之间用空格隔开,而中文是基于单词的。句子中的所有单词都可以连接起来以描述含义。例如,英文句子“我是学生”将用中文表示“我是学生”。计算机可以很容易地通过空间知道学…

计算机组成原理(微课版) -- 第二章 –– 数据信息的表示

第二章根据书本【计算机组成原理(微课版) 】进行整理 文章目录第二章 –– 数据信息的表示2.1 数据表示的作用2.2 数值数据的表示2.2.1 数的机器码表示1. 原码2. 反码3. 补码4. 变形补码5. 移码2.2.2 定点数表示1. 定点小数2. 定点整数3. 定点数能表示的范围2.2.3 浮点数表示1.…

2021-08-04

标签属性详解,HTML中html标签的作用 1、标签: 效果:声明是文档中的第一成分,坐落标签之前。 2、标签: 效果:此元素可告知浏览器其自身是一个HTML文档。 特点:manifest:值(url)为脱机运用界说缓存信息。 3、标签: 效果:标签用于界说文档的头部,它是一切头…

计算机组成原理(微课版) -- 第三章 -- 运算方法与运算器

第三章根据书本【计算机组成原理(微课版) 】进行整理 文章目录第三章 -- 运算方法与运算器3.2 定点加减法运算3.2.1 补码加减法运算方法1. 补码加法2. 补码减法3.2.2 溢出检测1. 溢出的概念2. 溢出检测3.2.3 加减法的逻辑实现1. 全加器3.3 定点乘法运算3.3.1 原码一位乘法1. 原…

数据库系统概论 ---- 第一章 -- 绪论(重要知识点)

前言 将 【数据库系统概论 ---- 第一章 – 绪论】中重要的知识点进行归纳整理 文章目录前言1. 数据库的4个基本概念2. 数据库管理系统(DBMS)的主要功能3. 与数据库相关的四种语言及其英文缩写4. 数据管理技术经历的三个阶段5. 数据库系统的特点6. 数据模型7. 数据描述的三个领域…