广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript原型Prototype详情
  • 148
分享到

JavaScript原型Prototype详情

2024-04-02 19:04:59 148人浏览 薄情痞子
摘要

目录1、概述 1.1原型是什么 1.2获取原型 2、原型属性 2.1利用原型添加属性与方法。 2.2访问原型属性原型方法 3、自有属性与原型属性 3.1检测自有属性或者原型属性 4、

1、概述

1.1原型是什么

javascript中,函数是一个包含属性和方法的Function类型的对象。而原型(Prototype )就是Function类型对象的一个属性。

在函数定义是包含了prototype属性,它的初始值是一个空对象 。在JavaScript中并没有定义函数的原始类型,所以原型可以是任何类型。

原型是用于保存对象的共享属性和方法的,原型的属性和方法并不会影响函数本身的属性和方法。

示例代码验证如下:


function fun() {
  console.log('函数原型')
}
console.log(fun.prototype) // {}

fun.prototype返回的也是一个空对象,但是这不说明Object.prototype中没有属性或者方法,这些属性和方法为不可枚举的,示例代码如下所示:


function fun() {
  console.log('函数原型')
}

console.log(fun.prototype) // {}
// 通过 Object.getOwnPropertyNames() 获取全部属性
console.log(Object.getOwnPropertyNames(fun.prototype)) // [ 'constructor' ]

其中,constructor属性指向该构造函数的引用,代码如下:


// constructor属性

console.log(fun.prototype.constructor) // [Function: fun]

console.log(fun.prototype.constructor === fun) // true

1.2获取原型

了解了原型的概念以及作用之后,我们需要获取到原型才能对其进行操作,在JavaScript中获取原型的方式有两种,如下所示:

通过构造函数的prototype属性。

通过Object.getPrototypeOf(obj)方法。

这两个的区别就是构造函数的prototype属性一般只配合构造函数使用,而Object.getPrototypeOf(obj)方法一般是获取构造函数实例化后的对象的原型方法。

实例代码如下:


// 构造函数
function Person(name) {
  this.name = name
}

// 指向构造函数的原型
var p1 = Person.prototype

var person = new Person('一碗周')

// 指向构造函数的原型
var p2 = Object.getPrototypeOf(person)

console.log(p1 === p2) // true

获取原型后可以跟操作对象似的进行操作,因为原型本身就是一个对象。

2、原型属性

JavaScript中,函数本身也是一个包含了方法和属性的对象。接下将学习函数对象的另一个属性——prototype,这个属性的初始值是一个空对象。

2.1利用原型添加属性与方法。

为对象添加属性和方法的另一种用法就是通过原型为其添加。当为一个构造函数添加原型属性和原型方法时,通过该构造函数new出的所有对象共享该属性和方法。

PS:所谓的原型属性或者原型方法就是通过原型添加的属性或者方法。

添加属性和方法的方式具有如下几种方式

直接为其增加属性或者方法

通过Object.defineProperty()方法,添加属性或者方法。这种方式比第一种方式更具有安全性。

直接添加对象到原型。

示例代码如下所示:


//构造函数
function Fun() {}
//直接为构造函数添加属性和方法
Fun.prototype.str = '这是一个字符串'
Fun.prototype.fn = function () {
  console.log('这是一个方法')
}
//通过 defineProperty 添加属性或者方法
Object.defineProperty(Fun.prototype, 'MyFun', {
  value: function () {
    console.log('this is MyFun')
  },
})
//测试
console.log(Fun.prototype.str)
Fun.prototype.fn()
Fun.prototype.MyFun()
var fun = new Fun()
fun.MyFun()
//直接为其定义个对象覆盖到之前的原型上
Fun.prototype = {
  name: '一碗周',
  fun: function () {
    console.log('this is function')
  },
}
Fun.prototype.fun()
var fun = new Fun()
fun.fun()

2.2访问原型属性原型方法

对于原型来说,最重要的一点就是它的实时性 。由于在JavaScript中,几乎所有的对象都是通过传引用的方式来传递的,因此我们所创建的的每个新对象实体中并没有一份属于自己的原型副本。这就意味着我们随时修改prototype属性,并且由同一构造器创建的所有对象的prototype属性也都会同时改变,包括我们之间通过构造器创建的属性和方法。

还是上面那段代码我们向原型中添加一个新方法,并调用,示例代码如下所示:


Fun.prototype.fn = function () {
  console.log('这是一个方法')
}
fun.fn() //这是一个方法

我们之前创建的对象可以访问新加的原型属性和原型方法。

3、自有属性与原型属性

我们先来创建一个构造函数,并为其添加两个原型属性。


//构造函数
function Fun() {}
//添加原型属性和方法
Fun.prototype.name = '一碗粥'
Fun.prototype.print = function () {
  console.log('this is function')
}

在通过该构造函数创建一个对象,为其设置属性和方法


//通过构造函数创建对象
var fun = new Fun()
//为对象添加属性和方法
fun.name = '一碗周'
fun.SayMe = function () {
  console.log('this is SayMe')
}

现在我们的fun对象,拥有自有属性/方法两个,原型属性/方法两个。我们依次来访问这些属性和方法。


//访问属性和方法
console.log(fun.name) // 一碗周
fun.SayMe() // this is SayMe
fun.print() // this is function


当我们访问name属性时,JavaScript引擎会遍历fun这个对象的所有属性,并返回name属性的值。SayMe()方法也是样的道理。但是到print()方法时,JavaScript引擎还是会遍历这个对象所有属性,这时就找不到一个叫print()方法了,接下来JavaScript引擎就会访问创建当前对象的构造器函数的原型,也就是我们的Fun.prototype,如果其中有该属性,则立即返回,否则返回undefined或者抛出异常

结论:当有自有属性时,优先访问自有属性,访问完自有属性再去访问原型属性 。

3.1检测自有属性或者原型属性

现在已经知道自有属性和原型属性的概念以及用途了,但是我们怎么知道一个属性时自由属性还是原有属性,JavaScript中提供以下两种方式来检测一个属性的情况

使用Object.prototype.hasOwnProperty(prop)方法来检测prop属性是否是自由属性,该方法返回一个布尔值,如果是自有属性则返回true,否则返回false。

来使用in关键字来检测对象以及原型链中是否具有指定属性。

测试代码如下:


// 通过Object.prototype.hasOwnProperty(prop)方法检测是否为自有属性
console.log(fun.hasOwnProperty('name')) // true
console.log(fun.hasOwnProperty('print')) // false
// 如果一个不存在的属性检测结果也是为false
console.log(fun.hasOwnProperty('SayMe')) // true

// 通过 in 运算符
console.log('name' in fun) // true
console.log('print' in fun) // true
console.log('SayMe' in fun) // true

通过测试我们发现,这两个方法并不能检测一个属性是不是一个自有属性或者原型属性,但是将这两个方法结合起来就可以检测是自有属性还是原型属性了,

示例代码如下:


function DetectionAttributes(obj, attr) {
  if (attr in obj) {
    if (obj.hasOwnProperty(attr)) {
      // 如果是自有属性属性返回1
      return 1
    } else {
      // 如果是原型属性返回0
      return 0
    }
  } else {
    // 没有这个属性返回 -1
    return -1
  }
}


测试如下:

console.log(DetectionAttributes(fun, 'name')) // 1
console.log(DetectionAttributes(fun, 'print')) // 0
console.log(DetectionAttributes(fun, 'SayMe')) // 1

4、isPrototypeOf()方法

isPrototypeOf()方法用来检测一个对象是否存在于另一个对象的原型链中,如果存在就返回true,否则就返回false。

实例代码如下所示:


// 定义一个对象,用于赋值给原型对象
var obj = function () {
  this.name = '一碗周'
}
var Hero = function () {} // 定义构造函数
// 将定义的对象赋值给构造函数的原型
Hero.prototype = obj

// 通过Hero创建对象
var hero1 = new Hero()
var hero2 = new Hero()
// 判断创建的两个对象是否在 obj 的原型链中
console.log(obj.isPrototypeOf(hero1)) // true
console.log(obj.isPrototypeOf(hero2)) // true

5、扩展内置对象

JavaScript中的内置对象有些也具prototype属性,利用内置对象的prototype属性可以为内置对象扩展属性和方法。

通过原型扩展内置对象的属性和方法非常灵活,根据个性化要求制定JavaScript语言的具体内容。

扩展内置对象的方式有两种,具体如下所示:

通过直接新增属性和方法。

通过Object对象的defineProperty()方法为其新增属性或者方法。这种方式会比第一种方式要好,是创建的属性和方法更具有安全性

示例代码如下所示:


// 为 Object 扩展属性和方法
// 使用第一种方式
Object.prototype.MyPrint = function () {
  console.log('this is MyPrint()')
}
// 使用第二种方式
Object.defineProperty(Object.prototype, 'MyInput', {
  value: function () {
    console.log('this is MyInput()')
  },
})
// 调用
Object.prototype.MyPrint() // this is MyPrint()
Object.prototype.MyInput() // this is MyInput()

6、结语

这篇文章介绍了JavaScript中的原型的概念、原型属性、如何检测自有属性和原型属性以及如何扩展内置对象

到此这篇关于JavaScript原型Prototype详情的文章就介绍到这了,更多相关JavaScript原型内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: JavaScript原型Prototype详情

本文链接: https://www.lsjlt.com/news/158902.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JavaScript原型Prototype详情
    目录1、概述 1.1原型是什么 1.2获取原型 2、原型属性 2.1利用原型添加属性与方法。 2.2访问原型属性原型方法 3、自有属性与原型属性 3.1检测自有属性或者原型属性 4、...
    99+
    2022-11-12
  • 原型和原型链 prototype和proto的区别详情
    目录1、原型2、原型链2.1 constructor构造函数2.2 call/apply2.3 new()1、原型 原型是function对象下的属性,它定义了构造函数的共同祖先,也...
    99+
    2022-11-12
  • JavaScript 原型与原型链详情
    目录1、prototype(显式原型)2、__proto__(隐式原型)3、constructor(构造函数)4、new的原理5、原型链5.1 原型链的作用5.2 构造函数的__pr...
    99+
    2022-11-12
  • JavaScript原型Prototype怎么使用
    这篇文章主要讲解了“JavaScript原型Prototype怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript原型Prototype怎么使用”吧!1、概述1.1原型...
    99+
    2023-06-21
  • JavaScript设计模式之原型模式详情
    目录前言案例回顾原型的拓展前言 设计模式呢最多的可能是用到类,我们去通过类来封装一些实用的方法,通过设计模式去实现各个方法之间的解耦等,由于JS中的继承是用原型链继承的,所以原型模式...
    99+
    2022-11-13
  • 什么是Prototype原型模式
    本篇内容介绍了“什么是Prototype原型模式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!前言在设计模...
    99+
    2022-10-19
  • Prototype原型模式怎么实现
    本篇内容介绍了“Prototype原型模式怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! Pro...
    99+
    2022-10-19
  • JavaScript函数及其prototype详解
    目录一、定义二、函数执行三、函数是对象[typeof instanceof]四、prototype五、实例方法&静态方法六、闭包七、通过调用方法的形式来间接调用函数:appl...
    99+
    2023-03-14
    javascript prototype详解 Javascript prototype理解 js中prototype的作用
  • 在JavaScript实例对象中改写原型方法详情
    目录在JavaScript中,我们通常可以像下面的代码这样来简单地定义一个类: var sample = function() { // constructor code...
    99+
    2022-11-12
  • 详解JavaScript的原型与原型链
    目录详解原型与原型链构造函数原型对象 访问原型设置原型检测原型prototype、__proto__、constructor之间的关系原型链原型链的作用普通对象与函数对象经...
    99+
    2022-11-13
  • PHP原型模式Prototype Pattern如何使用
    本文小编为大家详细介绍“PHP原型模式Prototype Pattern如何使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“PHP原型模式Prototype Pattern如何使用”文章能帮助大家解决疑惑,下面跟着小...
    99+
    2023-07-05
  • .Net创建型设计模式之原型模式(Prototype)
    目录一、动机(Motivation)二、意图(Intent)三、结构(Structure)四、模式的组成五、 原型模式的具体实现六、原型模式的实现要点:1、原型模式的优点:2、原型模...
    99+
    2022-11-13
  • JavaScript原型链详解
    目录1、构造函数和实例2、属性Prototype3、属性__proto__4、访问原型上的方法5、构造函数也有__proto__6、构造函数的原型也有__proto__7、Objec...
    99+
    2022-11-12
  • Javascript 原型与原型链深入详解
    目录前言对象原型原型链javascript中的类new的实现instanceof的实现javascript的继承总结前言 在前端这块领域,原型与原型链是每一个前端 er 必须掌握的概...
    99+
    2022-11-13
  • 详解JavaScript中的原型和原型链
    目录原型链图原型必备知识prototype属性(显示原型)proto属性(隐式原型)constructor属性总结 原型链图 原型必备知识 要了解原型就必须搞清三个属性:__pro...
    99+
    2022-11-12
  • 一文详解JavaScript中prototype的使用
    目录prototype初步认识函数有prototype属性,函数创建的对象没有获得当前对象的属性父和子的扩展子的proto和prototype的区别扩展得到的东西到底从哪来的prot...
    99+
    2022-11-13
  • JavaScript原型与实例详解
    目录构造函数实例原型三者的关系prototype属性属性或成员的搜索原则总结构造函数 实例 原型三者的关系 1.任何函数都有一个prototype属性,该属性是一个对象 func...
    99+
    2022-11-12
  • 详解JavaScript原始数据类型Symbol
    目录简介描述信息命名冲突私有属性总结简介 创建symbol变量最简单的方法是用Symbol()函数。sysmbol变量有两点比较特别: 1.它可以作为对象属性名。只有字符串和 sym...
    99+
    2022-11-12
  • C#异步原理详情
    目录一、关于第一点的说明二、关于第二点的说明三、关于第三点的说明四、关于第四点的说明五、关于第五点的说明前言: 用async关键字和await表达式表达的异步操作在C#5便发布了,其...
    99+
    2022-11-12
  • PythonAsyncio调度原理详情
    目录前言1.基本介绍2.EventLoop的调度实现3.网络IO事件的处理前言 在文章《Python Asyncio中Coroutines,Tasks,Future可等待对...
    99+
    2022-11-11
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作