资讯专栏INFORMATION COLUMN

弄清原型和原型链

enda / 3037人阅读

摘要:四条大规则原型和原型链,大体可以用以下几条规则概括,弄清楚了这几条,也就基本吃透了原型和原型链。上图帮助理解吧实例的隐式原型属性指向其构造函数的显式原型属性。原型相关方法判断一个对象是否在原型链上可以用,判断某一个属性是否是自身属性可以用。

四条大规则

原型和原型链,大体可以用以下几条规则概括,弄清楚了这几条,也就基本吃透了原型和原型链。

所有的引用类型都有一个__proto__属性,属性值是一个普通对象

所有的函数都有一个prototype属性,属性值也是一个普通对象

所有引用类型的__proto__属性值指向其构造函数的prototype属性值

当试图得到一个对象的某个属性值时,如果这个对象本身没有该属性,就会去它的__proto__(它构造函数的prototype)中查找

(为了方便起见,下文中__proto__用隐式原型代替,prototype用显式原型代替)
举个栗子:

// 构造函数
function Human(name) {
    this.name = name;
}
Human.prototype.introduce = function(){
    console.log("My name is", this.name);
}

var somebody = new Human("somebody");
console.log(Human.prototype); // Function
console.log(Human.prototype.constructor === Human); // true
console.log(somebody.__proto__ === Human.prototype);  // true
somebody.introduce(); // "My name is somebody"

在上述例子中,Human是构造函数,而somebody是Human的一个实例。从console输出结果可以验证,构造函数的显式原型的constructor属性指向它本身,实例的隐式原型属性指向其构造函数的显式原型。

在实例somebody中并没有introduce方法,该方法实际是在Human.prototype中,由上述第四条,当试图得到一个对象的某个属性值时,如果这个对象本身没有该属性,就会去它的__proto__(它构造函数的prototype)中查找,所以somebody的introduce方法实际上是somebody.__proto__.introduce,也就是Human.prototype.introduce。

上图帮助理解吧~

实例的隐式原型属性指向其构造函数的显式原型属性。
所有的一层一层的__proto__连起来,就构成了原型链。例如,在Object.prototype上有一方法toString,而somebody也有,但其实somebody的toString方法并非自身所有(除非多带带有声明),而是来自于somebody.__proto__.__proto__.__proto__(即Object.prototype),这一点可以通过hasOwnProperty证明。

原型相关方法

判断一个对象是否在原型链上可以用instanceof,判断某一个属性是否是自身属性可以用hasOwnProperty。

console.log(somebody.hasOwnProperty("name")) // true
console.log(somebody instanceof Object); // true

//语法
// obj.hasOwnProperty(prop)
// object instanceof constructor

后续再出一期与new运算符相关的还有与原型继承、class相关的吧,排期ing。

参考阅读

MDN: instanceof
MDN: constructor
MDN: hasOwnProperty

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96329.html

相关文章

  • 深入理解Javascript原型关系

    摘要:如下所示在规范中,已经正式把属性添加到规范中也可以通过设置和获取对象的原型对象对象之间的关系可以用下图来表示但规范主要介绍了如何利用构造函数去构建原型关系。 前言 在软件工程中,代码重用的模式极为重要,因为他们可以显著地减少软件开发的成本。在那些主流的基于类的语言(比如Java,C++)中都是通过继承(extend)来实现代码复用,同时类继承引入了一套类型规范。而JavaScript是...

    ethernet 评论0 收藏0
  • 关於Javascript中的new运算符,构造函数与原型一些理解

    摘要:前言文章主要基于高级程序设计总结的基本重写了全文补充知识点新增实例优化排版新增检测方法技巧用法构造函数创建一个用护定义的对象类型的实例或具有构造函数的内置对象类型之一命令执行构造函数返回一个实例对象构造函数一个指定对象实例的类型的函数传惨一 前言 文章主要基于>总结的!!!PS: 2018/05/09 基本重写了全文,补充知识点,新增实例,优化排版PS: 2018/05/11 新增检测...

    cikenerd 评论0 收藏0
  • 详解Object.create(null)

    摘要:要添加到新对象的可枚举新添加的属性是其自身的属性,而不是其原型链上的属性的属性。大家可能会注意到,第一个参数使用了。也就是说将设置成了新创建对象的原型,自然就不会有原型链上的属性。至此,我相信大家已经对两者的区别十分清楚了。 在Vue和Vuex的源码中,作者都使用了Object.create(null)来初始化一个新对象。为什么不用更简洁的{}呢?在SegmentFault和Stack...

    yanwei 评论0 收藏0
  • JavaScript由浅及深了解原型(一)

    摘要:但是该方法有个缺点就是看不出该对象的类型,于是乎构造函数模式应运而生。当然,如果细心的朋友应该会发现函数名首字母大写了,这是约定在构造函数时将首字母大写。这时候,聪明的人应该都可以想到,将构造函数模式和原型模式组合起来就可以了。 一.什么是js对象 1.简单理解js对象 在了解原型链之前,我们先要弄清楚什么是JavaScript的对象,JavaScript对象又由哪些组成。有人说一个程...

    YorkChen 评论0 收藏0
  • constructor, prototype, __proto__ 详解

    摘要:接下解释和属性同样拿上面的代码来解释输出首先给构造函数的原型对象赋给方法,由构造函数创建的实例会继承原型对象上的方法。 本文为了解决以下问题: __proto__(实际原型)和prototype(原型属性)不一样!!! constructor属性(原型对象中包含这个属性,实例当中也同样会继承这个属性) prototype属性(constructor.prototype原型对象) __...

    lifesimple 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<