《JavaScript 模式》读书笔记(3)— 字面量和构造函数3

这是字面量和构造函数的最后一篇内容,其中包括了JSON、正则表达式字面量,基本值类型包装器等知识点。也是十分重要的哦。五、JSONJSON是指JavaScript对象表示以及数据传输格式。它是一种

大家好,又见面了,我是你们的朋友全栈君。

  这是字面量和构造函数的最后一篇内容,其中包括了JSON、正则表达式字面量,基本值类型包装器等知识点。也是十分重要的哦。

 

五、JSON

  JSON是指JavaScript对象表示以及数据传输格式。它是一种轻量级数据交换格式,且可以很方便地用于多种语言,尤其是在JavaScript中。实际上,对于JSON而言,只是一个数组和对象字面量表示方法的组合:

{"name":"value","some":[1,2,3]}

  JSON和文字对象之间唯一的区别,就是在JSON中,属性名称需要包装在引号中才能成为合法的JSON。而在对象字面量中,仅当属性名称不是有效的标识符时才会需要引号,比如:字符之间有空格{“first name”:””Dave}。

  此外,JSON字符串中,不能使用函数或正则表达式字面量。

 

使用JSON

  注意,并不推荐盲目使用eval()对任意JSON字符串进行求值,其原因在于安全性的影响。如果使用JSON.parse()方法解析字符串,其安全性会更好。

// 一个输入JSON字符串
var jstr = '{"name":"value","some":[1,2,3]}';

// 反模式
var data = eval('(' + jstr + ')');

// 优先使用的方法
var data = JSON.parse(jstr);
console.log(data.name); // value

  与JSON.parse()相对的方法是JSON.stringify()。它可以将任意的对象或数组序列化为一个JSON字符串。

var dog = {
    name:'Fido',
    dob:new Date(),
    legs:[1,2,3,4]
};
var jsonstr = JSON.stringify(dog);

 

六、正则表达式字面量

  JavaScript中的正则表达式也是对象,可以用两种方法创建:

    1、使用new RegExp()构造函数。

    2、使用正则表达式字面量。

// 正则表达式字面量
var re = /\\/gm;

// 构造函数
var re = new RegExp('\\\\','gm');

  正如上面的代码,字面量表示法更加简短,并且不需要使用“类”的构造函数方式思考。优先选择字面量表示法创建正则表达式。

  此外,在使用构造函数时,不仅需要转义引号,还需要双反斜杠。如上代码,这里需要四个反斜杠才能匹配单个反斜杠。使得其难以阅读和修改。

 

正则表达式字面量语法

  正则表达式字面量表示法使用了斜杠(分隔号“/”)来包装用于匹配的正则表达式模式。在第二个斜杠之后,可以将该模式修改为不加引号的字母形式:

  • g——全局匹配
  • m——多行
  • i——大小写敏感匹配

  模式修改器可以允许任何顺序或者组合方式出现:var re = /pattern/gmi;

  还有一个要注意的是,在ES5之前,字面量在解析时只有一次创建了一个对象。也就是说,如果在一个循环中创建了相同的正则表达式,那么后面返回的对象与前面创建的对象相同,并且所有的属性都将被设置为第一次的值。这种行为已经在ES5中得到了改变,并且字面量会创建新的对象。

  最后要说明的是,调用RegExp()时不使用new的行为与使用new的行为时相同的。

 

七、基本值类型包装器

  JavaScript有五个基本的值类型:数字、字符串、布尔、null和undefined。除了null和undefined以外,其他三个具有所谓的基本包装对象。可以使用内置构造函数Number(),String()和Boolean()创建包装对象。

  为了说明基本(primitive)数字和数字对象(object)之间的差异,请看:

// 一个基本数值
var n = 100;
console.log(typeof n);//输出"number"

// 一个数值Number对象
var nobj = new Number(100);
console.log(typeof nobj);// 输出"object"

  包装对象包含了一些有用的属性和方法。比如,数字对象具有形如toFixed()和toExponential()的方法。字符串对象具有substring()、charAt()、toLowerCase()等方法以及length属性。与基本值类型相比较而言,这些包装对象的方法用起来十分方便,这也是用这种方法创建对象的一个很好的理由。但是这些方法在基本值类型上也能够起作用。只要调用这些方法,基本值类型就可以在后台被临时转换为一个对象,并且表现的犹如一个对象。

// 用来作为对象基本字符串
var s = "hello";
console.log(s.toUpperCase());// "HELLO"

// 值本身可以作为一个对象
"monkey".slice(3,6); // "key"

// 与数值的方法相同
(22 / 7).toPrecision(3); // "3.14"

  由于基本值类型也可以充当对象,只要需要它们这样做,不过通常并没有理由去使用更为冗长的包装构造函数。很显然,比如当可以简单地使用“hi”时,就不必编写“new String(“hi”);”这样冗长的语句。

// 避免使用以下结构:
var s = new String("my string");
var n = new Number(101);
var b = new Boolean(true);

// 更好且更加简单的语句
var s = "my string";
var n = 101;
var b = true;

  通常使用包装对象的原因之一是您有扩充值以及持久保存状态的需要。这是由于基本值类型并不是对象,他们不可能扩充属性。

// 基本字符串
var greet = "Hello there";

// 为了使用split()方法,基本数据类型被转换成对象
greet.split(' ')[0]; // "Hello"

// 试图增加一个原始数据类型并不会导致错误
greet.smile = true;

// 但是它并不会实际运行
typeof greet.smile; // "undefined"

  上面的代码中,greet只能被临时转换成对象,以使得该方法/属性可以访问,且运行时不会产生错误。另一个方面,如果使用new String()来定义一个对象greet,那么对其扩充的smile属性将会按照预期运行。扩充一个字符串、数字或布尔值的情况比较少见,除非这种行为就是您所需要的,否则可能并不需要包装构造函数。

  当使用时没有带new操作符时,包装构造函数将传递给它们的参数转换成一个基本类型值:

typeof Number(1);// 输出“number”
typeof Number("1");// 输出“number”
typeof Number(new Number());// 输出“number”
typeof String(1);// 输出“string”
typeof Boolean(1);// 输出“boolean”

 

八、错误对象

  JavaScript中有一些内置错误构造函数(error constructor),比如Error()、SyntaxError()、TypeError()以及其他,这些错误构造函数都带有throw语句。通过这些错误构造函数创建的错误对象具有下列属性:

  • name:用于创建对象的构造函数的名称属性。它可以是一般的“Error”或者更为专门的构造函数,比如“RangeError”。
  • message:当创建对象时传递给构造函数的字符串。

 

  错误对象也还有一些其他的属性,比如发生错误的行号和文件名,但这些额外属性都是浏览器扩展属性,在多个浏览器实现中并不一致,因而并不可靠。

  另一方面,throw适用于任何对象,并不一定是由某个错误构造函数所创建的对象,因此可以选择抛出自己的对象:

function genericErrorHandler() {
    console.log("错误处理中....")
}
try {
    throw {
        name: "MyErrortype",//自定义错误类型
        message: "oops",
        extra: "This is rather embarrassing",
        remedy: genericErrorHandler // 指定应该处理该错误的函数
    };
} catch (e) {
    // 通知用户
    alert(e.message);//输出"oops"
    // 优美的处理错误
    e.remedy(); // 调用函数genericErrorHandler()
}

  错误构造函数以函数的形式调用(不带new)时,其表现行为与构造函数(带new)相同,并且返回同一个错误对象。

 

  我们这篇文章整体的内容就结束了,我们主要学习了对象字面量、数组字面量、正则表达式字面量、以及构造函数和new、还有一些其他的内置构造函数比如不建议使用的String()、Number()、Boolean()等,此外还讨论了多种不同的Error()构造函数。

  注意:在一般情况下,除了Date()构造函数,很少需要使用其他内置构造函数。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/124394.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60000, active 20, maxActive 20

    com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60000, active 20, maxActive 20目录异常现象异常描述解决方案注意事项异常现象com.alibaba.druid.pool.GetConnectionTimeoutException:waitmillis60000,active20,maxActive20,creating0异常描述从异常现象中com.alibaba.druid.pool.GetConnectionTimeout…

    2022年7月23日
  • finsh初步

    finsh初步一.finsh在RT-Thread中被设计成一个独立的线程,它试图从外部设备中获得用户的输入,然后对用户命令进行解析执行。正确使用finsh需要一个关联过程:rt_hw_board_init()函数调用串口初始化函数rt_hw_usart_init(),此函数初始化串口,并向系统注册“usart1”设备,接着系统调用rt_console_set_device()函数设置“usart1…

    2022年5月11日
  • 6G要启动了! 6G究竟有多快?你真的应该提前知道

    点击上方蓝色字体,关注我们 写在前面 6G概念研究在今年启动。按照过去通信发展的规律推测,6G的理论下载速度可以达到每秒1TB,预计2020年将正式开始6G研发,2030年投入商用…

    2021年6月21日
  • 4g模块怎么使用_STM32库开发实战指南:基于STM32F4

    4g模块怎么使用_STM32库开发实战指南:基于STM32F4这部分一直再看,资料都已经整理好了,但是一直没有汇总。接下来就详细的看一下,GSM这部分是怎么实现的。

    2022年10月26日
  • pycharm换python版本需要重新下载第三方类吗_pycharm自带python吗

    pycharm换python版本需要重新下载第三方类吗_pycharm自带python吗今天刚配置完python和opencv的环境,发现在PowerShell上能成功使用OpenCV,并且输入importcv2后无错误出现,如下图:但在PyCharm上编写完程序后,会出现“ModuleNotFoundError:Nomodulenamed‘cv2’”的错误。在观看众多的博客后,从这篇博客中受益良多(https://blog.csdn.net/qq_25603827/article/details/84556416),最终发现了问题解决方法。根本问题在于你没有把python环境变

    2022年8月25日
  • c++ 字符串流 sstream(常用于格式转换)

    c++ 字符串流 sstream(常用于格式转换)点我进入原文c++字符串流sstream(常用于格式转换)  使用stringstream对象简化类型转换C++标准库中的提供了比ANSIC的更高级的一些功能,即单纯性、类型安全和可扩展性。在本文中,我将展示怎样使用这些库来实现安全和自动的类型转换。为什么要学习如果你已习惯了风格的转换,也许你首先会问:为什么要花

    2022年6月4日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号