JavaScript创建对象—从es5到es6

ArcGIS 10.2.2自带Python 2.7.5环境配置全攻略:从pip安装到gdal、arcpy调用 本文详细指导如何在ArcGIS 10.2.2自带的Python 2.7.5环境中进行高效配置。核心内容包括安装pip包管理器、部署gdal等关键地理数据处理库,并确保arcpy模块的无缝调用。通过解决路径配置与PyCharm集成问题,帮助用户在此经典环境中构建稳定、兼容的地理信息自动化工作流,有效连接ArcGIS桌面功能与Python脚本编程。 阅读详情

本文主要讲述了使用JavaScript创建对象的几种方式,分别是传统的Object构造函数、对象字面量、工厂模式、构造函数模式、原型模式、组合模式,以及es6的class定义类。然后从babel的角度探究es5与es6创建对象的区别。

1.创建对象的几种方式

es6出现之前,ECMAScript中是没有类的概念的,对象的实例化都是通过调用function声明的构造函数实现。es6出现之后,才有了使用class定义类的方式。以下介绍几种js中创建对象的方式:

(1)Object构造函数和对象字面量

在早期js开发中,很多开发者会使用Object构造函数的方式来创建一个对象,通过调用Object构造函数new一个Object对象,然后再给这个对象的每一个属性和方法进行赋值,代码如下所示:

 var person = new Object();
 person.age = 22;
 person.name = 'Dolanf';
 person.code = function() {
     console.log(‘hello world!’);
 };

后来出现了对象字面量的写法,由于使用对象字面量创建对象的写法简单直观,所以Object构造函数写法渐渐被对象字面量的写法所取代,对象字面量是通过在一个大括号里面使用键值对的方式表示每一个属性和方法,每一个键值对之间使用逗号隔开,代码如下所示:

var person = {
    age: 22,
    name: 'Dolanf',
    code: function() {
         console.log('hello world!');
    }
}

虽然对象字面量简单直观,但是上面两种方法都存在一个共同的问题:当需要创建很多很多个Person对象的时候,只能一个一个去创建,每一个对象的方法和属性都需要单独写,这使得代码没有丝毫复用性可言,违背了对象封装的特性。于是乎,工厂模式就随之出现了。

(2)工厂模式

工厂模式通过将对象的创建封装到一个方法中,再通过在调用该方法时传入参数而实现对象的实例化,解决了以上提到的产生大量重复代码的问题,如下所示:

function createPerson(age, name) { 
    var o = new Object();
    o.age = age;
    o.name = name;
    o.code = function() {
         console.log('hello world!');
    };

    return o;
}

var person1 = createPerson(11, '小白');
var person2 = createPerson(12, '小黑');

但是工厂模式也存在一个不足,就是通过该方法创建的对象的构造函数全都是Object,没有辨识度。没有办法通过构造函数辨别一个对象到底是Person还是Dog,亦或是Cat。于是乎,为了解决这个问题,就引入了构造函数模式。

(3)构造函数模式

构造函数模式就是通过定义一个function函数,然后通过this给对象的属性和方法进行赋值。当我们实例化对象时,只需在该函数前面加一个new关键字就可以了。

function Person(age, name) { 
    this.age = age;
    this.name = name;
    this.code = function() {
         console.log('hello world!');
    };
}

var person1 = new Person(11, '小白');
var person2 = new Person(12, '小黑');

构造函数模式解决了工厂模式中的对象识别问题,通过:

console.log(person1 instanceof Person);  // true

可以看出person1能成功被识别为一个Person对象。
但是,构造函数模式也同样存在一个缺点,就是构造函数里的属性和方法在每个对象上都要实例化一遍,包括对象共用的属性和方法,这样就造成了代码的复用性差的问题。所以大多数人会考虑将构造函数模式和原型模式组合起来使用。在这里先介绍一下原型模式。

(4)原型模式

原型模式是通过将所有的属性和方法都定义在其prototype属性上,达到这些属性和方法能被所有的实例所共享的目的。代码如下所示:

function Person(age, name) { 
    Person.prototype.age = age;
    Person.prototype.name = name;
    Person.prototype.code = function() {
         console.log('hello world!');
    };
}

var person1 = new Person();
var person2 = new Person();

当然,这种方法在项目开发中是没有人会使用的,因为当一个对象上的属性改变时,所有对象上的属性也会随之改变,这是非常不切实际的。至于原型模式的原理,会在下文的原型链中解释。在这里提及原型模式是为了介绍以下的构造函数+原型组合模式:

(5)构造函数+原型组合模式

组合模式是将构造函数模式和原型模式结合在一起,继承了它们优点的同时又避免了各自的缺点。它将具有各自特点的属性和方法定义在构造函数中,将实例间共享的属性和方法定义在prototype上,成为了在es6出现之前使用最普遍的一种创建对象模式。

function  Person(age, name) { 
    this.age = age;
    this.name = name;
    this.cry = function() {
         console.log(name + 'is crying!!! T^T');
    }
}
Person.prototype = {
    constructor: Person,
    sayName: function() {
        console.log(this.name);
    }
}
var person1 = new Person(11, '小白');
var person2 = new Person(12, '小黑');

(6)class定义类

当然,前面讲的都是浮云,现在大家都用class定义类啦,class的出现就是为了让定义类能更加简单。回到上面的Person构造函数上,我们现在将其改造成使用class定义的方式:

class Person{ 
    constructor(age, name) {
        this.age = age;
        this.name = name;
        this.cry = function() {
         console.log(name + 'is crying!!! T^T');
        }
    }
    sayName() {
        console.log(this.name);
    }
}
var person1 = new Person(11, '小白');
var person2 = new Person(12, '小黑');

使用class定义类跟上面的构造函数+原型组合模式有一些相似之处,但又有所区别。
class定义的类上有个constructor方法,这就是构造方法,该方法会返回一个实例对象,this代表的就是实例对象,这跟上边的构造函数模式很类似。
此外,class上的方法都是定义在prototype上的,这又跟原型模式有一些相似之处,这个class里的sayName等价于

Person.protorype.sayName = function() {
    console.log(this.name);
}

虽然class定义的类跟es5中的构造函数+原型组合模式很相似,但是他们还是存在不少区别的,下面对比如下:

2.es5与es6定义对象的区别

1)class的构造函数必须使用new进行调用,普通构造函数不用new也可执行。
2)class不存在变量提升,es5中的function存在变量提升。
3)class内部定义的方法不可枚举,es5在prototype上定义的方法可以枚举。

为什么会存在以上这些区别呢?下面使用babel将es6转化成es5看看它的实现过程就知道了。

3.es6中class转化为es5

下面将讲述使用babel将以上的class定义Person类转换成使用es5实现:

es6代码:

class Person{ 
    constructor(age, name) {
        this.age = age;
        this.name = name;
        this.cry = function() {
         console.log(name + 'is crying!!! T^T');
        }
    }
    sayName() {
        console.log(this.name);
    }
}
var person1 = new Person(11, '小白');
var person2 = new Person(12, '小黑');

使用babel转化成的es5后的代码:

'use strict'; // es6中class使用的是严格模式

// 处理class中的方法
var _createClass = function () { 
   function defineProperties(target, props) { 
      for (var i = 0; i < props.length; i++) { 
         var descriptor = props[i]; 
         // 默认不可枚举
         descriptor.enumerable = descriptor.enumerable        || false; 
         descriptor.configurable = true; 
         if ("value" in descriptor) descriptor.writable = true; 
         Object.defineProperty(target, descriptor.key, descriptor);
      } 
   } 
   return function (Constructor, protoProps, staticProps) { 
      if (protoProps) defineProperties(Constructor.prototype, protoProps); 
      if (staticProps) defineProperties(Constructor, staticProps); 
      return Constructor; 
   }; 
}();

// 对构造函数进行判定
function _classCallCheck(instance, Constructor) { 
   if (!(instance instanceof Constructor)) { 
      throw new TypeError("Cannot call a class as a function"); 
   }
}

// class Person转换为 es5的function
var Person = function () {
    function Person(age, name) {
        // 调用了_classCallCheck检查Person是否为构造函数
        _classCallCheck(this, Person); 

        this.age = age;
        this.name = name;
        this.cry = function () {
            console.log(name + 'is crying!!! T^T');
        };
    }

    // 调用_createClass处理定义在class中的方法。
    _createClass(Person, [{
        key: 'sayName',
        value: function sayName() {
            console.log(this.name);
        }
    }]);

    return Person;
}();

var person1 = new Person(11, '小白');
var person2 = new Person(12, '小黑');

这里我将转换后的代码格式化并加上了一些注释。
从以上代码可以看出,class主要是通过两个函数实现:_createClass和_classCallCheck。
所以为什么会存在上述区别呢:
1)class的构造函数必须使用new进行调用,普通构造函数不用new也可执行。
class中的constructor会直接转化为function构造函数,然后在function中通过 _classCallCheck的检查该function是否是一个Constructor。因为有_classCallCheck检查必须是instanceof Constructor,所以class必须使用new进行调用。

2)class不存在变量提升,es5中的function存在变量提升。
class转变成了函数表达式进行声明,因为是函数表达式声明的,所以class不存在变量提升。

3)class内部定义的方法不可枚举,es5在prototype上定义的方法可以枚举。
class中定义的方法会传入 _createClass中,然后 Object.defineProperty将其定义在Constructor.prototype上。所以class中的方法都是定义在Constructor.prototype上的。
由于defineProperties中的

descriptor.enumerable = descriptor.enumerable || false;

将属性的 enumerable默认为false,所以class中定义的方法不可枚举。

HTML流光爱心(完整代码) HTML语言实现红蓝色流光爱心效果的完整代码。 阅读详情

相关推荐

Ubuntu使用cmake出现Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed

解决 Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed

qq_44225529的博客 1万+

ES6--创建对象

ES6 class类创建对象 /* 实战出真知 */

weixin_43614868的博客 736

AI+Xmind自动生成测试用例(思维导图格式)

最后:我是Walker,一个热爱分享编程知识的程序员,希望能够帮助到你!

Think_and_work的博客 2333

Js ES5创建对象的九种方式

ES6之后,定义了Class的概念,我们可以通过其快速的实现对象创建,那么,在这之前都有哪些方式实现对象创建呢?本文旨在探索这一点

鹏北海的博客 638

Duplicate Cleaner Pro 5.16 保姆级教程:如何用哈希值精准清理重复文件(附音频/视频模式详解)

本文详细介绍了Duplicate Cleaner Pro 5.16如何利用哈希值技术精准清理重复文件,特别针对音频、视频和图片等多媒体文件提供了专业解决方案。通过哈希算法比对和多媒体特征识别,帮助用户高效管理存储空间,提升文件整理效率。

weixin_27032989的博客 567

整理的15个公开且可直接使用的电力视觉输电线路领域数据集

而巡检数据是目前来说影响我们做科研的最大阻碍,为此本内容主要总结了,现有的且公开免费的巡检数据集,供大家使用。STN PLAD数据集133个航拍图像,五个电力部件:电力塔及其塔的ID、绝缘子,防震锤,联板(yoke),图像的尺寸在5472×3648到5472×3078。IDID数据集:2000张图像,包含三个类别,正常绝缘子,破损绝缘子和闪络绝缘子三个类别,用于目标检测的实验。TTPLA数据集,用于实例分割,1100张尺寸为3840×2160,包含两个类别,电力杆塔和电力线。主要用于电力杆塔的目标检测。

weixin_42048361的博客 5019

JS基础--ES5创建对象的7种模式

以下内容总结自《JavaScript高级程序设计(第3版)》 一. 工厂模式 ECMAScript中无法创建类,所以开发人员用函数封装以特定接口创建对象的细节。 function createPerson(name, age, job) { var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName...

yilia学习小园 648

华为OD机考双机位C卷 - 构成正方形的数量 (Java & Python& JS & C/C++ & GO )

华为OD机考双机位C卷 - 成正方形的数量 (OD上机考试双机位C卷)。提供在线OJ刷题。Java、C++、Python、GO语言、C语言、JavaScript题解,并提供完整思路讲解。

算法大师! 5939

学习ES6(二十二) -- 创建对象详解

面向对象是遵循真实世界建模的软件开发范例。面向对象,将程序视为对象的集合,这些对象通过称为方法的机制相互通信。ES6也支持这些面向对象的组件。 面向对象的编程概念 首先,让我们了解 对象-对象是任何实体的实时表示。根据Grady Brooch的说法,每个对象都具有3个特征- 状态-由对象的属性描述。 行为-描述对象的行为。 身份-唯一值,...

qq_34975445的博客 805

LeRobot 官方论文:一个用于端到端机器人学习的开源库

本文介绍了一个名为LeRobot的开源库,旨在解决机器人学习领域的碎片化问题。该库提供了端到端的技术栈,包括统一的机器人中间件API、标准化的数据集格式(LeRobotDataset)、优化的推理栈以及多种最先进机器人学习算法的实现。LeRobot支持多种低成本开源机器人平台(如SO-10X、ALOHA-2等),通过共享中间件实现便捷的遥操作和数据收集。其数据集格式已广泛应用于社区,截至2025年9月已有16,000多个数据集公开共享。该库还支持流式处理大规模数据,降低了研究门槛。在模型方面,LeRobot

2506_90492529的博客 907

YOLOv8自动驾驶系统 —— 夜间低光照条件 详细说明和完整代码

本文提出一种针对夜间低光照优化的自动驾驶车道保持系统方案,基于YOLOv8模型改进,包含三大核心技术:1.采用Retinex理论的多尺度低光增强算法,结合自适应伽马校正;2.改进YOLOv8的车道检测模型,通过夜间专用数据集训练,增加抗眩光处理;3.多传感器融合框架,整合可见光与红外图像。系统实现动态逆透视变换和参数调整,在Jetson Orin硬件上达到30ms级实时性能。测试显示在无照明、眩光干扰等极端场景下保持稳定,代码已开源。扩展方向包括V2X协同定位和自适应大灯联动控制。

u010117029的博客 598

ES6面向对象思想和构造对象方式

ES6面向对象思想和构造对象方式

YY的博客 525

西门子SMART PLC增量式PID(完整梯形图FC)

西门子PLC自带的PID指令是基于位置型的PID,位置型PID的算法公式和详细介绍,大家可以参看《PID专栏》的其它文章,这里不再赘述。本篇博文直接给出代码部分的讲解,不设计太多公式和理论的推导。限于本人能力,文中难免出现错误和不足之处,诚恳欢迎大家的批评和指正。同时感谢大家的订阅和关注。SMART200 PLC系统自带的PID指令解析,可以参看下面这篇文章:SMART PLC PID算法基本解析(附公式)_RXXW_Dor的博客-优快云博客_plc的pid算法在态运行中,控制器调节输出值,使偏差 (e

RXXW_Dor的博客 8149

【JavaScript】ES5/ES6 创建对象与继承

1. ES5 创建对象的方式 在 JavaScript 中,创建对象的方式有很多种,最常用的一般是通过字面量的方式,而要创建实例对象则一般通过创建一个构造函数,通过 new 关键字来构造。 虽然 Object 函数和字面量都可以创建对象,但同时也会有一个问题:使用一个接口创建多个对象时,会出现大量重复代码。下面来介绍一些创建对象的变体。 1.1 工厂模式 function createPerson...

weixin_34121282的博客 297

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

【web高级进阶之JS】创建对象+操作对象属性+操作数组方法(ES5~ES6)详解

没啥好说的 自己看吧 绝对有收获

weixin_55846296的博客 902

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

es5 的面向对象和 es6 的面向对象

es5的面向对象是通过new一个构造函数实现的 es6的面向对象是通过class实现的es6的class就是面向对象的语法糖(实现同样的功能但是代码更少 更加简洁) 面向对象是一个概念或者编程思想,面向对象是相对于面向过程来讲的,面向对象方法,把相关的数据和方法组织为一个整体来看待,从更高的层次来进行系统建模,更贴近失误的自然运行模式 (在js中一切皆为对象 比如说数组object number string 等等 这些都是内置对象 该怎么怎么自定义对象? es5的时候没有像后台语言一样的clas

jfdkslafjkladsjf的博客 232

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

2.ES6对比ES5一些不同

ECMAScript 6   ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了。   Mozilla公司将在这个标准的基础上,推出JavaScript 2.0。   ECMAScript和JavaScript到底是什么关系?很多初学者会感到困惑,简单来说,   ECMAScript是JavaScript语言的国际标准,Java...

weixin_30550081的博客 114

创建对象—从es5到es6

本文主要讲述了使用JavaScript创建对象的几种方式,分别是传统的Object构造函数、对象字面量、工厂模式、构造函数模式、原型模式、组合模式,以及es6的class定义类。然后从babel的角度探究es5与es6创建对象的区别。 1.创建对象的几种方式 (1).Object构造函数和对象字面量 在早期js开发中,很多开发者会使用Object构造函数的方式来创建一个对象,通过调用Object构...

mengmeng12138的博客 207

ES6的class

ES6的class

ShyN_的博客 90

JavaScript创建对象与构造函数

基于原型的面向对象语法糖,更接近传统面向对象语言。:属于构造函数本身的属性和方法,无需实例化即可访问。:若构造函数返回一个对象,则返回该对象;:创建对象、绑定原型、执行构造函数、返回对象。:属于实例对象的属性和方法,每个实例独立拥有。:静态方法无实例上下文,无法直接访问实例属性。:基于现有对象原型创建新对象,适合原型继承。:通过函数封装对象创建逻辑,避免重复代码。返回新对象(若构造函数无显式返回对象)。:实例可访问构造函数原型上的属性和方法。:最简洁的方式,适合创建简单对象。

2301_82023822的博客 1344

es5 的面向对象和 es6 的面向对象以及类(class)

es5 的面向对象和 es6 的面向对象 es5 的面向对象是通过 new 一个构造函数实现的 es6 的面向对象是通过 class 实现的 es6 的 class 就是面向对象的语法糖(实现同样的功能 但是代码更少 更加简洁) 面向对象是一个概念或者编程思想,面向对象是相对于面向过程来讲的,面向对象方法,把相关的数据和方法组织为一个整体来看待,从更高的层次来进行系统建模,更贴近事物的自然运行模式 (在 js 中一切皆对象 比如说数组 object number string 等等 这些都是内置对象 那么怎

weixin_60408555的博客 1551

一文详解-JavaScript中 es5 原型和 es6-class

有不少小伙子应该会有这个感觉 大家都在说原型 很重要,那为什么我却用不到?原因不外乎这几个:于是乎,既然用不到,那就不用学,从自我做起,拒绝内卷。理解满分。。。。然而残酷的真相是,只有技术是自己可以实实在在的去把控的,命运还是掌握在自己手中。刚刚想撸起袖子好好干, 一看这个神图。 “算了,上号吧”。下面小弟尽量以最直白和简洁的图文给你梳理 ese5 和原型之间的关系。封装!!! 当我们想抽象某些公共业务 方便复用或者使结构更加清晰的时候便会用到。 面向对象三大特征:比如 我们想创建一个我们会这么写如果 我

不懂先生的博客 1220

原型链和ES6和ES5创建对象并实现继承

当实例化调用属性和方法的时候,会在实例化本身找,如果没有就沿着__proto__属性找到原型对象的__proto__属性,找原型对象上的属性和方法(如果找到就用),如果没有就一直往上走,直到找到Object 原型对象的__proto__属性为null为止,这一系列由__proto__属性串连起来的原型对象为原型链。构造函数初始化的时候,会创造一个特殊的实例化对象,该对象为原型对象,构造函数的prototype属性指向原型对象。②所有函数都有一个prototype(原型)属性,属性值是一个普通的对象。

MISS_zhang_0110的博客 212

ES5、ES6 创建对象区别

ES5 创建对象 // 父类 -- 超类 -- super function Person(name,age){ this.name=name this.age=age } Person.prototype.say=function(){ console.log(this.name,this.age); } // 子类

weixin_66705999的博客 1052

ES5与ES6之创建对象

ES5及ES6写对象的对比 经常会遇到需要在js 写 ES6 写对象,写了个实例供大家参考 ES5创建对象 // 类的基本写法 function Person(name, sex) { var self = this; this._name = name; // 外部可见的成员变量 this._sex = sex; var no = Person.population; // 静态变量的...

youlinhuanyan的博客 390

JavaScript 创建对象模式与最佳实践

在JavaScript中“创建对象”是一个复杂的话题。这门语言提供了很多种创建对象的方式,不论新手还是老手都可能对此感到无所适从,不知道应该选择哪一种。不过,尽管创建对象的方法很多,看上去语法差异也很大,但实际上它们的相似性可能比你所以为的要多。本文将带领你踏上一段梳理对象创建方法的旅程,为你揭示不同方法之间的依赖与递进关系。 对象字面量 我们的第一站毫无疑问就是创建对象最简单

384
上一篇: 被多数人误解的nth-of-type
Dolanf
博客等级 码龄9年 1粉丝 2原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值