博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入理解原型
阅读量:5299 次
发布时间:2019-06-14

本文共 3578 字,大约阅读时间需要 11 分钟。

无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。所有原型对象都会自动获得一个consturctor属性,这个属性指向prototype属性所在函数的指针。Person.prototype.constructor 指向Person。通过这个构造函数可以继续为原型对象添加其他属性和方法.

1.prototype:

只要我们定义一个函数,prototype作为函数的属性存在了,它的初始值是一个对象。

function Person () {}Person.prototype

函数的prototype属性

2.给对象添加属性和方法

给通过构造函数创建的对象添加属性和方法:在函数内部通过this给构造函数返回的对象添加属性。

function Person (name, age) {    this.name = name;    this.age = age;}var person1 = new Person();

通过构造函数的prototype属性给对象添加属性和方法,这种方式添加的属性和方法会被所有的对象实例共享。

function Person (name, age) {    this.name = name;    this.age = age;}Person.prototype.sayName = function() {    return this.name;}Person.prototype.breathes = '空气';var person1 = new Person('张三', 20);var person2 = new Person('李四', '21');person1.sayName();

注意:一定要前在原型中定义方法和属性,然后再使用:

person2.eat();Person.prototype.eat = function() {    console.log('吃饭啦');}

注意:原型对象中属性和对象自己的属性是有区别的,对象自己属性默认是可配置可枚举的,而我们在原型中添加的属性是不可配置的,但确是可枚举。

function Person (name, age) {      this.name = name;      this.age = age;    }    Person.prototype.sayName = function() {        return this.name;    }    Person.prototype.breathes = '空气';    var person1 = new Person('张三', 20);    delete person1.sayName;    console.log(person1.sayName())   // '张三'    for(propName in person1){      console.log(propName)       // name age sayName breathes    }

3.覆盖原型中属性

如果对象出现了和原型对象中同名的属性或方法,原型的属性和方法会被覆盖掉。这是因为,我们在访问对象的属性或方法时,优先在对象自己的属性列表中查找,如果找到的话,就使用自己的属性,如果找不到的,就去原型对象中查找。

在下面的示例中,原型对象中sayName方法被对象自己的sayName方法遮挡住了,所以最终调用的是对象自己的sayName方法。

function Person (name, age) {    this.name = name;    this.age = age;}Person.prototype.sayName = function() {    return this.name;}var person1 = new Person('李四', 20);person1.sayName = function() {    console.log('对象自己的sayName方法')}person1.sayName();      // '对象自己的sayName方法'

4.hasOwnProperty()方法和in操作符的区别

判断对象中是否存在某个属性,除了使用in操作符,还可以使用hasOwnProperty()方法。hasOwnProperty()方法只在对象自己的属性列表中搜索;而in操作符,先在对象自己的属性列表中查找,如果找不到,接着去原型对象的属性列表中查找。

function Person (myname, myage) {  this.name = myname;  this.age = myage;}Person.prototype.sayName = function() {  console.log(this.name)}var person1 = new Person('小明', 18, '女');// 使用hasOwnProperty()方法console.log(person1.hasOwnProperty('name'))     // tureconsole.log(person1.hasOwnProperty('sayName'))  // false// 使用in操作符console.log('sayName' in person1)               // true

5.isPrototypeOf()方法

该方法是用来判断一个对象是否是另一个对象的原型。例如:

var monkey = {    feeds: '香蕉',    breathes: '空气'}function Human (name) {    this.name = name;}Human.prototype = monkey;接下来我们来判断monkey对象是否是Human原型:var person1 = new Human('李四');monkey.isPrototypeOf(person1)验证person1的原型是否是monkeyconsole.log(Object.getPrototypeOf(person1))console.log(Object.getPrototypeOf(person1) === monkey)

6.proto

我们先前讲过,当我们访问一个当前对象中没有的属性时,会去prototype对象中查找。

var developer = new Human('李四');developer.feeds = '大米饭';developer.hacks = 'JavaScript';developer.hacks     // 'JavaScript'

当我们访问developer对象中不存在的breathes属性时,就会去原型对象中查找,仿佛有一个神秘的链接指向原型对象。

developer.breathes;  // 'air'

在大多数浏览器中都是以__proto__属性作为这个神秘的链接

console.log(developer.__proto__ === monkey);  // true

在学习的过程中,我们可以使用这个链接,但是在实际的项目开发中不要使用它,因为并不是所有的浏览器都有__proto__属性。

我们可以使用Object.getPrototypeOf()代替它。

7.扩展(增强)内置的构造函数创建的对象

内置的构造函数有ArrayStringObjectFunction等,我们可以通过改变原型对象的方式增强由这些构造函数创建的对象。

例如,给数组添加一个inArray()方法,用于判断数组中是否包含某个元素:

Array.prototype.inArray = function (ele) {for (var i = 0; i < this.length; i++) {  if(this[i] === ele) {    return true;  }}return false;};var colors = ['red', 'green', 'blue'];console.log(colors.inArray('red'));        // trueconsole.log(colors.inArray('purple'));     // false

 

转载于:https://www.cnblogs.com/zhoulifeng/p/7525615.html

你可能感兴趣的文章
Caffe: Cannot create Cublas handle. Cublas won't be available
查看>>
Linux 下 LXD 容器搭建 Hadoop 集群
查看>>
mysql describe
查看>>
Hello博客园
查看>>
apache自带压力测试工具ab的使用及解析
查看>>
Android基础入门教程——8.1.2 Android中的13种Drawable
查看>>
C语言作业3
查看>>
.Net Core中的通用主机(二)——托管服务
查看>>
C#使用Xamarin开发可移植移动应用(2.Xamarin.Forms布局,本篇很长,注意)附源码
查看>>
koogra--Excel文件读取利器
查看>>
ASP.NET 使用ajaxupload.js插件出现上传较大文件失败的解决方法
查看>>
jenkins搭建
查看>>
C#中使用Split分隔字符串的技巧
查看>>
(springboot)freemarker(二)
查看>>
linux下golang gRPC配置详解
查看>>
mongodb 简单使用说明
查看>>
eclipse的调试方法的简单介绍
查看>>
OneAPM 云监控部署与试用体验
查看>>
加固linux
查看>>
wget 升级
查看>>