文章来源: 学习通http://www.bdgxy.com/

目录
  • 1、概述
    • 1.1原型是什么
    • 1.2获取原型
  • 2、原型属性
    • 2.1利用原型添加属性与方法。
    • 2.2访问原型属性原型方法
  • 3、自有属性与原型属性
    • 3.1检测自有属性或者原型属性
  • 4、isPrototypeOf()方法
  • 5、扩展内置对象
  • 6、结语

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)) {// 如果是自有属性属性返回1return 1} else {// 如果是原型属性返回0return 0}} else {// 没有这个属性返回 -1return -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原型内容请搜索菜鸟教程www.piaodoo.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持菜鸟教程www.piaodoo.com!

JavaScript原型Prototype详情相关推荐

  1. 深入理解javascript原型和闭包(3)——prototype原型

    既typeof之后的另一位老朋友! prototype也是我们的老朋友,即使不了解的人,也应该都听过它的大名.如果它还是您的新朋友,我估计您也是javascript的新朋友. 在咱们的第一节(深入理解 ...

  2. 白话解释 Javascript 原型继承(prototype inheritance)

    来源: 个人博客 白话解释 Javascript 原型继承(prototype inheritance) 什么是继承? 学过"面向对象"的同学们是否还记得,老师整天挂在嘴边的面向对 ...

  3. 浅谈JavaScript中的原型prototype

    之前看过一些关于原型的知识,但总是看了以后没有及时应用,导致再看到一些代码是遇到还是搞不清楚,借此机会谈一下我对prototype的理解. 1.再谈原型之前,我们要知道什么是构造器函数,型如下例: f ...

  4. JavaScript中的原型prototype及原型链

    原型prototype 简介: prototype里面放置了一种类的公用的方法(构造函数:constructor)和类的信息.因此可以用来作为一种类的共享数据实现机制.这种共享的另一个好处的是减少了内 ...

  5. 一张图带你搞懂Javascript原型链关系

    在某天,我听了一个老师的公开课,一张图搞懂了原型链. 老师花两天时间理解.整理的,他讲了两个小时我们当时就听懂了. 今天我把他整理出来,分享给大家.也让我自己巩固加深一下. 就是这张图: 为了更好的图 ...

  6. 深入解析JavaScript 原型继承

    JavaScript 原型继承,学习js面向对象的朋友可以看看.十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批评指正. Object.prototype Ja ...

  7. 如何理解JavaScript原型

    Javascript的原型总会给人产生一些困惑,无论是经验丰富的专家,还是作者自己也时常表现出对这个概念某些有限的理解,我认为这样的困惑在我们一开始接触原型时就已经产生了,它们常常和new.const ...

  8. 深入理解 JavaScript 原型

    前言 原型,作为前端开发者,或多或少都有听说.你可能一直想了解它,但是由于各种原因还没有了解,现在就跟随我来一起探索它吧.本文将由浅入深,一点一点揭开 JavaScript 原型的神秘面纱.(需要了解 ...

  9. JavaScript 笔记 ( Prototype )

    这阵子实在好忙 ( 这样说好像也不是一两个月了... ),然后因为工作伙伴都是 JavaScript 神之等级的工程师,从中也学到不少知识,毕竟就是要和强者工作才会成长呀!为了想好好瞭解他们写的程式码 ...

最新文章

  1. Kafka:你必须要知道集群内部工作原理的一些事!
  2. windows环境下的zookeeper安装
  3. AngularJS实战之Controller之间的通信
  4. [JavaWeb-JavaScript]JavaScript_Array数组对象
  5. SQL查询语句中的 limit offset(转 )
  6. Java开发笔记(一百五十)C3P0连接池的用法
  7. 使用Gps获取经纬度
  8. 提高网站速度,分析工具page speed中文教程
  9. 大物实验数据处理——用C求标准误差、标准偏差、标准偏差、相对误差
  10. win8 安装双系统 ubuntu 过程
  11. 微软推出Azure Sphere漏洞奖励计划,最高奖金10万美元
  12. c# .net对接企业微信小助手 接口请求时长预警
  13. cd命令回到上级目录和回到根目录
  14. Python中range函数的用法
  15. java 拼音 联想_solr6.6.2之拼音联想
  16. 拼多多API接口,(item_get_app - 根据ID取商品详情原数据)
  17. latex公式中的空格如何表示?
  18. Discuz论坛代码
  19. 推荐一本非常不错的书——李笑来的《把时间当作朋友》
  20. easyExcel模板数据导入数据库

热门文章

  1. ROS进阶——在ROS平台的搭建自己的机器人
  2. 有关调音台的专业英文词汇
  3. PMP考试的一次通过率真实的是多少?
  4. B 站 18 岁高中生火了:历时 200 天,成功撸了个机器人!
  5. 关于ESD静电测试以及实际案例的修改(怎么让你的PCB更加好过ESD)
  6. MFC中的Create();函数
  7. linux gzip 解压 函数,获取http的gzip内容,并解压
  8. Xcode各版本官方下载及百度云盘下载, Mac和IOS及Xcode版本历史
  9. python 视频抽帧_python通过ffmgep从视频中抽帧的方法
  10. 强制双休!腾讯调整加班机制,21点前必须离开工位