资讯专栏INFORMATION COLUMN

原型与原型链

dayday_up / 2039人阅读

摘要:原型属性在函数被定义时创建,初始值是一个空对象没有自身属性的对象。为新建对象添加方法和属性的方式利用原型构造器中原型属性几个相关方法和属性判断一个属性是自身属性还是原型属性。来自知乎的一张图,很清晰面向对象编程指南的原型链图

sync github

原型属性 prototype

在函数被定义时创建,初始值是一个"空"对象(没有自身属性的对象)。

为新建对象添加方法和属性的方式

利用原型

// 1 构造器中
function Gadget(name, color) {
    this.name = name;
}

// 2 原型属性
Gadget.prototype.price = 66;
几个相关方法和属性

hasOwnProperty() 判断一个属性是自身属性还是原型属性。

通常,在for infor of 中,需要使用 hasOwnProperty()~

propertyIsEnumerable() 该方法会对所有的非内建对象属性返回 true

const newtoy = new Gadget("webcam");

// 对于内建属性和方法来说,不可枚举
newtoy.propertyIsEnumerable("constructor"); // false

// 任何来自原型链中的属性都会返回false,包括那些在`for-in`循环中可枚举的属性
newtoy.propertyIsEnumerable("price");   // false

// notice
newtoy.constructor.prototype.propertyIsEnumerable("price"); // true

isPrototypeOf() 判断当前对象是否是另一个对象的原型

Object.getPrototypeOf() ES5适用。获取对象的原型。效果同 特殊属性 __proto__

__proto__

notice: 不要在实际的脚本中使用。另,__proto__prototype的区别,__proto__实际上是某个实例对象的属性,而prototype则属于构造器函数的属性。

原型陷阱

当我们对原型对象执行完全替换时,可能会触发原型链中某种异常

prototype.constructor属性是不可靠的

体会下面的输出内容

function Dog() {
    this.tail = true;
}
var benji = new Dog();
var rusty = new Dog();

Dog.prototype.say = function() {
    return "Woof!";
};

benji.say();    // "Woof!"
rusty.say();    // "Woof!"
benji.constructor === Dog;  // true
rusty.constructor === Dog;  // true

// 用一个自定义的新对象完全覆盖掉原有的原型对象
Dog.prototype = {
    paws: 4,
    hair: true,
};

// 发现通过构造函数创建的对象 prototype 对象并没有改变
typeof benji.paws;  // undefined
benji.say();    // Woof
typeof benji.__proto__.say; // function
typeof benji.__proto__.paws;    // undefined

// 通过构造函数创建的对象使用新的 prototype 对象
var lucy = new Dog();
lucy.say(); // TypeError: lucy.say is not a function
lucy.paws;  // 4
typeof lucy.__proto__.say; // undefined
typeof lucy.__proto__.paws; // number

//但是!!!注意此时新对象的 constructor 属性的指向
lucy.constructor;   // function Object(){[native code]}
benji.constructor;  // function Dog() {...}

// solve
Dog.prototype.constructor = Dog;
new Dog().constructor === Dog;  // true
lucy.constructor;   // function Dog() {...}

当我们重写某对象的 prototype 时, 需要重置相应的 constructor 属性。

Summary

来自知乎的一张图,很清晰

Reference

《JavaScript面向对象编程指南》

Javascript的原型链图 - wang z

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

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

相关文章

  • 《javascript高级程序设计》笔记:原型图解

    摘要:不理解没关系,下面会结合图例分析上一篇高级程序设计笔记创建对象下一篇高级程序设计笔记继承参考之原型链的解读三张图搞懂的原型对象与原型链继承与原型链 文章直接从原型图解开始的,如果对一些概念不太清除,可以结合后面几节查看 1. 图解原型链 1.1 铁三角关系(重点) function Person() {}; var p = new Person(); showImg(https://s...

    vspiders 评论0 收藏0
  • 【5】JavaScript 函数高级——原型原型深入理解(图解)

    摘要:探索是如何判断的表达式如果函数的显式原型对象在对象的隐式原型链上,返回,否则返回是通过自己产生的实例案例案例重要注意的显示原型和隐式原型是一样的。面试题测试题测试题报错对照下图理解 原型与原型链深入理解(图解) 原型(prototype) 函数的 prototype 属性(图) 每个函数都有一个prototype属性,它默认指向一个Object空对象(即称为:原型对象) 原型对象中有...

    马龙驹 评论0 收藏0
  • JavaScript中的原型原型

    摘要:前言作为前端高频面试题之一,相信很多小伙伴都有遇到过这个问题。 前言 作为前端高频面试题之一,相信很多小伙伴都有遇到过这个问题。那么你是否清楚完整的了解它呢? 国际惯例,让我们先抛出问题: 什么是原型、原型链 它们有什么特点 它们能做什么 怎么确定它们的关系 或许你已经有答案,或许你开始有点疑惑,无论是 get 新技能或是简单的温习一次,让我们一起去探究一番吧 如果文章中有出现纰...

    laoLiueizo 评论0 收藏0
  • 进击JavaScript之(四)原型原型

    摘要:每一个由构造函数创建的对象都会默认的连接到该神秘对象上。在构造方法中也具有类似的功能,因此也称其为类实例与对象实例一般是指某一个构造函数创建出来的对象,我们称为构造函数的实例实例就是对象。表示该原型是与什么构造函数联系起来的。 本文您将看到以下内容: 传统构造函数的问题 一些相关概念 认识原型 构造、原型、实例三角结构图 对象的原型链 函数的构造函数Function 一句话说明什么...

    XBaron 评论0 收藏0
  • 原型一:原型原型

    摘要:说白了,原型就是构造函数用来构造新实例的模板对象。什么是原型链先回答什么是原型。例如这个原型的原型就是这个构造函数的,既这个原型对象。这些原型对象通过像链子一样连起来,就叫做原型链。 原型链初步学习 这篇博客只是我初步理解原型链的一个个人学习笔记,写的比较粗略,且有的地方可能理解错误. 更多更专业的关于原型链的解释请看JavaScript深入之从原型到原型链和阮一峰的博客:Javas...

    MudOnTire 评论0 收藏0
  • JavaScript系列--浅析原型继承

    摘要:综上所述有原型链继承,构造函数继承经典继承,组合继承,寄生继承,寄生组合继承五种方法,寄生组合式继承,集寄生式继承和组合继承的优点于一身是实现基于类型继承的最有效方法。 一、前言 继承是面向对象(OOP)语言中的一个最为人津津乐道的概念。许多面对对象(OOP)语言都支持两种继承方式::接口继承 和 实现继承 。 接口继承只继承方法签名,而实现继承则继承实际的方法。由于js中方法没有签名...

    draveness 评论0 收藏0

发表评论

0条评论

dayday_up

|高级讲师

TA的文章

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