资讯专栏INFORMATION COLUMN

JavaScript - 原型&原型链

wean / 1504人阅读

摘要:可以看出,这个查找过程是一个链式的查找,每个对象都有一个到它自身原型对象的链接,这些链接组件的整个链条就是原型链。原型的构建字面量方式当通过字面量方式创建对象时,它的原型就是。

面向对象

JavaScript没有类(class)的概念的(ES6 中的class也只不过是语法糖,并非真正意义上的类),而在JavaScript中,在 JavaScript 中,除了 String, Number, Boolean Undefined, Null, Symbol 这 6 种基本类型外,其他所有数据都是 Object 类型。

在基于类的传统面向对象的编程语言中,对象由类实例化而来,实例化的过程中,类的属性和方法会拷贝到这个对象中;对象的继承实际上是类的继承,在定义子类继承于父类时,子类会将父类的属性和方法拷贝到自身当中。因此,这类语言中,对象创建和继承行为都是通过拷贝完成的。但在JavaScript中,对象的创建、对象的继承是不存在拷贝行为的。

原型和原型链

原型是为了共享多个对象之间的一些共有特性(属性或方法),这个功能也是任何一门面向对象的编程语言必须具备的。A、B两个对象的原型相同,那么它们必然有一些相同的特征。
JavaScript中的对象,都有一个内置属性[Prototype],指向这个对象的原型对象。当查找一个属性或方法时,如果在当前对象中找不到定义,会继续在当前对象的原型对象中查找;如果原型对象中依然没有找到,会继续在原型对象的原型中查找;如此继续,直到找到为止,或者查找到最顶层的原型对象中也没有找到(Object.prototype),就结束查找,返回undefined。可以看出,这个查找过程是一个链式的查找,每个对象都有一个到它自身原型对象的链接,这些链接组件的整个链条就是原型链。

Object.prototype: 最顶层的原型对象,这个对象中保存了最常用的方法,如toString、valueOf、hasOwnProperty等,因此我们才能在任何对象中使用这些方法。

原型的构建 字面量方式

当通过字面量方式创建对象时,它的原型就是Object.prototype。虽然我们无法直接访问内置属性[[Prototype]],但我们可以通过Object.getPrototypeOf()或对象的__proto__获取对象的原型。

let obj = {};
Object.getPrototypeOf(obj) === Object.prototype;   // true
(obj).__proto__  === Object.prototype;            // true
函数的构造调用

通过函数的构造调用(注意,我们不把它叫做构造函数,因为JavaScript中同样没有构造函数的概念,所有的函数都是平等的,只不过用来创建对象时,函数的调用方式不同而已)也是一种常用的创建对象的方式。基于同一个函数创建出来的对象,理应可以共享一些相同的属性或方法,但这些属性或方法如果放在Object.prototype里,那么所有的对象都可以使用它们了,作用域太大,显然不合适。于是,JavaScript在定义一个函数时,同时为这个函数定义了一个 默认的prototype属性,所有共享的属性或方法,都放到这个属性所指向的对象中。由此看出, 通过一个函数的构造调用创建的对象,它的原型就是这个函数的prototype指向的对象。

let f = function(name) { this.name = name };
f.prototype.getName = function() { return this.name; };
let obj = new f("123");
obj.getName();                  // 123
obj.__proto__ === f.prototype;  // true
Object.create()

第三种常用的创建对象的方式是使用Object.create()。 这个方法会以你传入的对象作为创建出来的对象的原型。

let obj = {};
let obj2 = Object.create(obj);
obj2.__proto__ === obj;       // true

这种方式还可以模拟对象的“继承”行为。

function Foo(name) {
        this.name = name;
}
Foo.prototype.myName = function() {
        return this.name;
};
function Bar (name,label) {
        Foo.call( this, name );   //
        this.label = label;
}
let  temp = Object.create( Foo.prototype );  
Bar.prototype = temp;
Bar.prototype.myLabel = function() {
        return this.label;
};
let a = new Bar( "a", "obj a" );
a.myName(); // "a"
a.myLabel(); // "obj a"
a.__proto__.__proto__ === Foo.prototype;  //true
 __proto__和prototype

__proto__指向当前对象的原型,prototype是函数才具有的属性,默认情况下,new 一个函数创建出的对象,其原型都指向这个函数的prototype属性。

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

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

相关文章

  • 温故js系列(15)-原型&原型&原型继承

    摘要:给添加属性给的原型对象添加属性原型链在中,每个对象都有一个属性,其保存着的地址就构成了对象的原型链。实例变量实例函数原型链继承有了原型链,就可以借助原型链实现继承。是中唯一一个处理属性但是不查找原型链的函数。 前端学习:教程&开发模块化/规范化/工程化/优化&工具/调试&值得关注的博客/Git&面试-前端资源汇总 欢迎提issues斧正:原型&原型链&原型继承 JavaScript-原...

    Ethan815 评论0 收藏0
  • 前端笔记——JS基础(原型&&原型

    摘要:基础原型原型链构造函数默认有这一行张三李四构造函数扩展其实是的语法糖其实是的语法糖其实是使用判断一个函数是否是一个变量的构造函数原型规则和示例所有的引用类型数组对象函数,都具有对象属性即可自有扩展的属性,除外所有的引用类型数组对象函数, JavaScript基础 —— 原型&&原型链 构造函数 function Foo(name, age) { this.name = na...

    n7then 评论0 收藏0
  • 图解javascript原型&原型

    我们在学习javascript时,经常会听到万物皆对象,但是呢,其实万物皆对象的对象也有区别。分为普通对象和函数对象。1.对象分为函数对象和普通对象    通过new Function()创建的对象都是函数对象,其他的都是普通对象。showImg(https://segmentfault.com/img/bVbtWre?w=526&h=252); 2.构造函数而提到new关键字,我们不得不提到构造...

    sutaking 评论0 收藏0
  • 深入JavaScript(一)this & Prototype

    摘要:然而事实上并不是。函数本身也是一个对象,但是给这个对象添加属性并不能影响。一图胜千言作者给出的解决方案,没有麻烦的,没有虚伪的,没有混淆视线的,原型链连接不再赤裸裸。所以是这样的一个函数以为构造函数,为原型。 注意:本文章是个人《You Don’t Know JS》的读书笔记。在看backbone源码的时候看到这么一小段,看上去很小,其实忽略了也没有太大理解的问题。但是不知道为什么,我...

    The question 评论0 收藏0
  • 探索 proto & prototype 与继承之间的关系

    摘要:而和的存在就是为了建立这种子类与父类间的联系。创建一个基本对象建立新对象与原型我把它理解为类之间的连接执行构造函数小结可以理解为类,也就是存储一类事物的基本信息。原型原型链和继承之间的关系。 原型 原型的背景 首先,你应该知道javascript是一门面向对象语言。 是对象,就具有继承性。 继承性,就是子类自动共享父类的数据结构和方法机制。 而prototype 和 __proto__...

    dockerclub 评论0 收藏0

发表评论

0条评论

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