资讯专栏INFORMATION COLUMN

JavaScript基础之创建对象、原型、原型对象、原型链

wangbjun / 1914人阅读

摘要:在最开始的时候,原型对象的设计主要是为了获取对象的构造函数。同理数组通过调用函数通过调用原型链中描述了原型链的概念,并将原型链作为实现继承的主要方法。

对象的创建

在JavaScript中创建一个对象有三种方式。可以通过对象直接量关键字newObject.create()函数来创建对象。

1. 对象直接量

创建对象最直接的方式就是在JavaScript代码中使用对象直接量。在ES5中对象直接量是由若干 名/值组成的映射表, 整个映射表由{}包含起来。每个名/值中间使用:进行分割,名/值之间使用,进行分割。

var o1 = {};
var o2 = {name: "javascript"}
var o3 = {title: "object", o2: o2} 
// 数组、日期、函数、正则等作为特殊的对象,这里暂不讨论
// ES6 也暂时不讨论

上面就是使用对象直接量创建对象,这种方式比较简单方便。

2. 通过new创建对象

通过关键字new + 函数调用,就可以创建一个新的对象。被调用的函数被称为构造函数。 根据高程中描述,使用 new + 调用函数 创建一个对象,这种方式会经历以下 4 个步骤:

(1) 创建一个新对象;
(2) 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象);
(3) 执行构造函数中的代码(为这个新对象添加属性);
(4) 返回新对象。

举个例子:

    var Foo = function(name) {
         this.name = name
    }
    
    var foo = new Foo("我"); 
    /*
        var foo = new Foo("我") 
        创建对象大致的流程是
        (1)  var obj = {};
        `高程`中步骤(2),(3)如果不清楚的小伙伴,可以参考下面的实现
        (2)、(3) Foo.call(obj); call 方法能够改变函数Foo的执行上下,把this指向obj,然后执行Foo函数
        (4) foo = obj;   
    */
    typeof foo; // "object"
    foo.constructor === Foo // true  
3. 通过Object.create() 创建对象

这里是ES5官方提供的一个创建对象的方法。

    var obj = {name: "javascript"};
    var newObj = Object.create(obj);
    newObj.name // => javascript
原型

JS中每个函数都可以看成一个对象,而原型(prototype)就是函数中的其中一个属性。这里要很清楚,原型是函数上面的一个属性,这个属性只有函数对象才能拥有,别的类型是没有prototype属性。而原型的作用就是它所引用的对象能够被拥有它的函数所构建的实例化对象所访问。

那么原型是怎么和对象建立联系的?

编写代码如下:

let obj = {name: "javascript"};
console.log(obj.name) // => javascript
console.log(obj)

控制台输出如下:

我们在程序中定义一个JavaScript对象,然后打印这个对象,这里除了前面定义的name属性外,还有另外一个__proto__属性。前面说道 函数 上面的 prototype(原型)所指向的对象能够拥有它的函数所构建的实例化对象所访问。至于具体怎么访问的细节没有说明。其实就是通过__proto__这个属性作为桥梁进行的联接。

let obj = {name: "javascript"};
console.log(obj.__proto__ === Object.prototype) //true

对比发现__proto__所指的对象和Object.prototype所指的是一样的。我们是可以认定__proto__就是这座桥梁,那么obj就能访问到Object.prototype所指的对象就是理所当然了。

于是我就在猜测在使用直接定义量去定义对象的时候,在底层的实现很有可能就是通过new Object()的这种方式实现的。

于是我编写了下面的测试代码:

 let obj = {name: "javascript"};
 let obj1 = new Object({name: "javascript"});

发现上面的obj与obj1两者数据结构基本一致。

原型对象

原型对象简单来说就是函数的原型所指向的对象。前面说原型的时候,说了Object.prototype所指对象就是Object(函数)的原型对象。 在每个函数的原型对象中,默认会有constructor属性,用于指向函数本身。

Object.prototype.constructor === Object // true
let Test = function() {console.log("test")};
Test.prototype.constructor === Test // true

在最开始的时候,原型对象的constructor设计主要是为了获取对象的构造函数。后来发现constructor属性易变,不可信。推荐使用instanceof。

var Test = function() {console.log("test")};
var test = new Test();
console.log(test.constructor); // Test
test.constructor = Object;
console.log(test.constructor); // Object
/*这里想使用 test.constructor 来判断是否是Test的实例化对象就不可信。而应该使用 instanceof */
test instanceof Test // true

原型对象有什么作用,主要实现对象的继承。

例如我们常用的对象、数组、函数都是得益于原型。

当我们使用变量直接量定义一个对象的时候,其实我们是没有定义它上面的这些能够调用的方法

let obj = {};


这些方法怎么来的,就是通过调用Object上面的原型对象而来的。

console.log(Object.prototype)


同理数组(通过调用Array.prototype),函数(通过调用Function.prototype)

原型链

ECMAScript中描述了原型链的概念,并将原型链作为实现继承的主要方法。其基本思想是利用原 型让一个引用类型继承另一个引用类型的属性和方法。简单回顾一下构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么,假如我们让原型对象等于另一个类型的实例,结果会怎么样呢?显然,此时的 原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数 的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实 例与原型的链条。这就是所谓原型链的基本概念。

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

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

相关文章

  • JS面向对象二:this/原型/new原理

    摘要:情况没有明确作用对象的情况下,通常为全局对象例如函数的回调函数,它的就是全局对象。正因如此,机器可以作为这类对象的标志,即面向对象语言中类的概念。所以机器又被称为构造函数。原型链也就是继承链。 JS面向对象二:this/原型链/new原理 阮一峰JavaScript教程:面向对象编程 阮一峰JavaScript教程:实例对象与 new 命令 阮一峰JavaScript教程:this 关...

    anRui 评论0 收藏0
  • SegmentFault 技术周刊 Vol.32 - 七夕将至,你的“对象”还好吗?

    摘要:很多情况下,通常一个人类,即创建了一个具体的对象。对象就是数据,对象本身不包含方法。类是相似对象的描述,称为类的定义,是该类对象的蓝图或原型。在中,对象通过对类的实体化形成的对象。一类的对象抽取出来。注意中,对象一定是通过类的实例化来的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 马上就要到七夕了,离年底老妈老爸...

    Lyux 评论0 收藏0
  • SegmentFault 技术周刊 Vol.32 - 七夕将至,你的“对象”还好吗?

    摘要:很多情况下,通常一个人类,即创建了一个具体的对象。对象就是数据,对象本身不包含方法。类是相似对象的描述,称为类的定义,是该类对象的蓝图或原型。在中,对象通过对类的实体化形成的对象。一类的对象抽取出来。注意中,对象一定是通过类的实例化来的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 马上就要到七夕了,离年底老妈老爸...

    AaronYuan 评论0 收藏0
  • SegmentFault 技术周刊 Vol.32 - 七夕将至,你的“对象”还好吗?

    摘要:很多情况下,通常一个人类,即创建了一个具体的对象。对象就是数据,对象本身不包含方法。类是相似对象的描述,称为类的定义,是该类对象的蓝图或原型。在中,对象通过对类的实体化形成的对象。一类的对象抽取出来。注意中,对象一定是通过类的实例化来的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 马上就要到七夕了,离年底老妈老爸...

    李昌杰 评论0 收藏0
  • JS面向对象的程序设计继承的实现 - 原型

    摘要:简单回顾一下构造函数原型和实例对象之间的关系每个构造函数都有一个原型对象。找到生成构造函数的原型对象的构造函数,搜索其原型对象,找到了。 JS面向对象的程序设计之继承的实现 - 原型链 前言:最近在细读Javascript高级程序设计,对于我而言,中文版,书中很多地方翻译的差强人意,所以用自己所理解的,尝试解读下。如有纰漏或错误,会非常感谢您的指出。文中绝大部分内容引用自《JavaS...

    zhaochunqi 评论0 收藏0

发表评论

0条评论

wangbjun

|高级讲师

TA的文章

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