安全基础 --- JSON + 函数声明

2023-11-18

JSON

格式:JSON(JavaScript Object Notation缩写)是一种用于数据交换的文本格式,目的是取代繁琐笨重的 XML 格式。

(1)规定

  1. 复合类型的值只能是数组或对象,不能是函数、正则表达式对象、日期对象。

  2. 原始类型的值只有四种:字符串、数值(必须以十进制表示)、布尔值和null(不能使用NaN, Infinity, -Infinityundefined)。

  3. 字符串必须使用双引号表示,不能使用单引号。

  4. 对象的键名必须放在双引号里面。

  5. 数组或对象最后一个成员的后面,不能加逗号。

(2)实例:

  • 合法JSON
["one", "two", "three"]
{ "one": 1, "two": 2, "three": 3 }
{"names": ["张三", "李四"] 
[ { "name": "张三"}, {"name": "李四"} ]
  • 不合法JSON
{ name: "张三", 'age': 32 }  // 属性名必须使用双引号

[32, 64, 128, 0xFFF] // 不能使用十六进制值

{ "name": "张三", "age": undefined } // 不能使用 undefined

{ "name": "张三",
  "birthday": new Date('Fri, 26 Aug 2011 07:13:10 GMT'),
  "getName": function () {
      return this.name;
  }
} // 属性值不能使用函数和日期对象

(3)JSON对象

JSON对象是 JavaScript 的原生对象,用来处理 JSON 格式数据。它有两个静态方法:JSON.stringify()JSON.parse()

<1> JSON.stringify()
[1] 基本用法

JSON.stringfy()方法将一个值转为JSON字符串,该字符串符合JSON格式,且可被JSON.parse()还原

例:

JSON.stringify('abc')  // ""abc""
JSON.stringify(1) // "1"
JSON.stringify(false) // false
JSON.stringify([])  // "[]"
JSON.stringify({})  // "{}"

JSON.stringify([1,"false",false])
// '[1,"false",false]'

JSON.stringfy({name:"张三"})
// '{name:张三}'

上方将各种类型的值,转为JSON字符串,对于原始类型,转换结果会带双引号
JSON.stringify('foo') === "foo" // false
JSON.stringify('foo') === "\"foo\""  // true
// 上面代码中,如果不是内层的双引号,将来还原的时候,引擎就无法知道原始值是布尔值还是字符串。

JSON.stringify()方法会忽略对象的不可遍历的属性

var obj = {};

Object.defineProperties(obj,{
    'foo':{
    value:1,
    enumerable:true
    },
    'bar':{
    value:2,
    enumerable:false
    }
});

JSON.stringify(obj);  // "{"foo":1}"

// bar是obj对象的不可遍历属性,JSON.stringify方法将会忽略这个属性
[2] 第二个参数

JSON.stringify()方法还可以接受一个数组,作为第二个参数,指定参数对象的哪些属性需要转为字符串

var obj = {
    'prop1':'value1',
    'prop2':'value2',
    'prop3':'value3'
};

var selectedProperties = ['prop1','prop2'];

JSON.stringify(obj,selectedProperties)
// "{"prop1":"value1","prop2":"value2"}"
// JSON.stringify()方法的第二个参数指定,只转prop1和prop2的两个属性

类似白名单的数组,只对对象的属性有效,对数组无效。

JSON.stringfy(['a','b'],[0]);
// "["a","b"]"

JSON.stringify({0:'a',1:'b'},['0']);
// "{"0":"a"}"

第二个参数还可以是函数,用来更改JSON.stringify()的返回值

function f(key,value) {
    if(typeof value === "number") {
        value = 2 * value;
    }
    return value;
}

JSON.stringify({a:1,b:2},f);
// '{"a":2,"b":4}'

// f函数,接受两个参数,分别是被转换的对象的键名和键值。键值为数值的话,将乘2,否则原样返回,

注意:这个处理函数是递归处理所有的键

var obj = {a:{b:1}}

function f(key.value) {
    console.log("[" + key + "]:" + value);
    return value;
}

JSON.stringify(obj.f);
//[]:[object object]
//[a]:[object object]
//[b]:1
//'{"a":{"b":1}}'

// 对象 obj 一共会被函数 f 处理三次,输出的最后那行是JSON.stringify()的默认输出,第一次键名为空,键值是整个对象的obj;第二次键名为a,键值是{b:1};第三次键名为b,键值为1

递归处理中,每一次处理的对象,都是前一次返回的值

var obj = {a:1};

function f(key,value) {
    if (typeof value === 'object') {
        return {b:2};
    }
    return value * 2;
}

JSON.stringify(obj,f);
// "{"b":4}"

// 上面代码中,f函数修改了对象obj,接着JSON.stringify()方法就递归处理修改后的对象obj

如果处理函数返回undefined或没有返回值,则该属性会被忽略

function f(key,value) {
    if (typeof(value) === "string") {
        return undefined;
    }
    return value;
}

JSON.stringify({a:"abc",b:123},f)
// '{"b":123}'

// a属性被处理后,返回undefined,于是该属性被忽略
[3] 第三个参数

JSON.stringify()还可以接受第三个参数,用于增加返回的JSON字符串的可读性

默认返回单行字符串,对于大型JSON对象,可读性差。第三个参数使得每个属性单独占据一行,并将每个属性前面添加指定的前缀(前缀不超过10个字符)

// 默认输出
JSON.stringify({p1:1,p2:2})
// JSON.stringify({p1:1,p2:2})

// 分行输出
JSON.stringify({p1:1,p2:2},null,'\t')
/*
{
    "p1":1,
    "p2":2
)
*/

// 第三个属性\t在每个属性前面添加一个制表符(从当前位置移动到下一个tab位置),然后分行显示

第三个属性如果是数字,则表示在每个属性前面添加的空格(不超过10个)

JSON.stringify({ p1: 1, p2: 2 }, null, 2);
/*
"{
  "p1": 1,
  "p2": 2
}"
*/
<2> JSON.parse()

JSON.parse()方法用于将 JSON 字符串转换成对应的值。

例1:

JSON.parse('{}');  // {}
JSON.parse('true');  // true
JSON.parse('"foo"');  // "foo"
JSON.parse('[1,5,"false"]');  // [1,5,"false"]
JSON.parse('null');  // null

var o = JSON.parse('{"name":"张三"}');
o.name  // 张三

例2:传入字符串不是有效的JSON格式,将报错

JSON.parse("'String'");
// 报错

// 双引号字符串中是一个单引号字符串,因为单引号字符串不符合JSON格式,所以报错

try...catch代码块,解析错误

try {
    JSON.parse("'String'");
}catch(e) {
    console.log('parsing error');
}

JSON.parse()方法接受一个处理函数,作为第二个参数,用法与JSON.stringify()方法类似

function f(key,value) {
    if (key === 'a') {
        return value + 10;
    }
    return value;
}

JSON.parse('{"a":1,"b":2}',f);
// {a:11,b:2}

// JSON.parse()的第二个参数是一个函数,如果键名是a,该函数会将键值加上10

函数声明

js中有三种声明函数的方法

(1)function命令

function命令声明的代码区块,就是一个函数。function命令后面是函数名,函数名后面是一对圆括号,里面是传入函数的参数。函数体放在大括号里面

function print(s) {
    console.log(s);
}

// 代码中命名了一个print函数,使用print()这种形式,就可以调用相应的代码,这叫做函数的声明

(2)函数表达式

funciton命令声明函数,还可采用变量赋值的写法

var print = function(s) {
    console.log(s);
}

// 将一个匿名函数赋值给变量,匿名函数又被称为函数表达式,赋值语句右侧只能放表达式

采用函数表达式声明函数时,function命令后面不带有函数名。加上函数名,则函数名只在函数体内部有效,在函数体外部无效

var print = funciton x() {
    coonsole.log(typeof x);
};

print();
// funciton

// 上面代码在函数表达式中,加入了函数x。x只在函数体内部可用,指代函数表达式本身,其他地方都不可用
// 两种用法:
//(1)函数体内部调用自身
//(2)方便除错(除错工具显示函数调用栈时,显示函数名,而不再显示这里是一个匿名函数)

var funciton  f()  {};

函数表达式末尾加分号,表示语句结束;而函数声明在结尾的大括号后面不用加分号。

(3)Function构造函数

var add = new Function(
    'x',
    'y',
    'return x + y'
);

// 等同于
function add(x,y) {
    return x + y;
}

// Function构造函数接受三个参数,除了最后一个参数是add函数的“函数体”,其他参数都是add函数的参数

可传递任意数量参数给Function构造函数,仅最后一个参数会被当做函数体;若仅一个参数,该参数就是函数体

var foo = new Function(
    'return "hello world";'
);

// 等同于
function foo() {
    return "hello world";
}

// function构造函数可不使用new命令,返回结果相同。(声明函数的方式不直观,无人使用)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

安全基础 --- JSON + 函数声明 的相关文章

随机推荐

  • 【计算机网络】计算机网络基础

    计算机是人类社会不可或缺的工具 而单独的一台计算机的功能也是有限的 计算机需要和其它的设备相互连接通信形成的计算机网络才能对人类发展带来巨大的影响 目录 计算机网络 通信协议 网络结构 网络边缘 接入网 网络核心 时延和吞吐量 时延 吞吐量
  • wchar_t char wstring string 项目转换

    wchar t char wstring string 项目转换 1 wchart t转wstring wchar t tmpRuleStr 10 0 wstring m tmpRuleStr wstring tmpRuleStr 2 ws
  • Mac安装python3

    可以在命令行中输入 brew install python3 但是出现了error 如下所示 tar Error opening archive Failed to open Users my Library Caches Homebrew
  • springBoot自动装载原理

    springBoot自动装载原理 启动类的核心组合注解 SpringBootApplication 点进去看看 组成 SpringBootApplication注解的三个核心注解 SpringBootConfiguration 继承自 Co
  • 【MySQL】数据库高级查询:修改表、DML语句、DQL语句

    修改表 1 修改表名 ALTER TABLE 旧表名 RENAME TO 新表名 TO为可选参数 使用与否不影响结果 2 添加字段 ALTER TABLE 表名 ADD 字段名 数据类型 属性 3 修改字段 ALTER TABLE 表名 C
  • Spring Bean作用域简介说明

    转自 Spring Bean作用域简介说明 Bean作用域简介 Bean作用域指一个Bean是否为单例模式 还是每次访问新实例 或一个Session一个新实例等方式 那么Bean作用域有哪几种呢 下文将一一道来 作用域 描述 singlet
  • springboot(三)———解决 8/24/2022 6:00类型转换为2022-08-24 06:00:00.0(MM/dd/yyyy H:mm与yyyy-MM-dd HH:mm:ss转换)

    输入 输出 代码 String datastring 8 24 22 6 00 String arrDate datastring split 3 StringBuffer stringBuffer new StringBuffer str
  • 停止和删除Hasplms服务(一)

    使用圣天诺HASP加密的软件都会启动一个叫做Hasplms或Sentinel LDK License Manager的服务项 这个服务是软件运行所必须的 但是在软件卸载后往往这个服务还在运行 重启电脑后也还继续运行 这就非常不厚道了 针对这
  • Gradle介绍1-入门和IDEA整合(Gradle Wrapper)

    1 Gradle 入门 1 1 Gradle 简介 Gradle 是一款Google 推出的基于 JVM 通用灵活的项目构建工具 支持 Maven JCenter 多种第三方仓库 支持传递性依赖管理 废弃了繁杂的xml 文件 转而使用简洁的
  • QGLWidget类的初始化顺序

    这里 我们用一个简单的opengl程序来了解一下QGLWidget类的结构 程序绘制了一个白色的正方形 1 QGLWidget类的定义 cpp view plain copy class Widget public QGLWidget Q
  • 在Linux(Redhat/CentOS)下安装MySQL之yum(rpm)在线安装方式

    在CentOS6之前 yum源默认存在MySQL yum install mysql server mysql client 在CentOS6之后 yum没有MySQL源 意味着我们要自己下载源 下载源 yum install url 安装
  • JMeter压力测试教程(超详细&小白版)

    目录 文章目录 jdk jmeter下载安装 jmeter应用启动 jmeter使用教程 jmeter测试结果分析 一 jdk jmeter下载安装 1 提前下载jdk和jmeter并配置环境 备注 jdk和jmeter版本需对应 否则后期
  • win10系统mysql开发常见问题集锦

    目录 一 mysql56 系统找不到指定文件 二 mysqldump Error Binlogging on server not active 无法导出数据 三 mysql备份导出的数据为空 四 mysql事件不执行 五 修改mysql密
  • python读取文件存到excel中

    用xlwt模块执行代码报下面的错 ValueError column index 256 not an int in range 256 xlwt 模块看源码说最大列只支持255列 所以超过这个值就报错了 改用xlsxwriter模块 im
  • pygame实现飞机大战-第二版代码分析

    目录 一 原代码 第一部分 精灵定义部分 第二部分 游戏运行部分 二 代码分析 一 代码整体结构 1 定义了main 2 创建游戏对象 3 启动游戏 二 局部代码分析 1 精灵的定义 2 主游戏类定义 3 主程序运行 4 细节分析 三 心得
  • Gradle for Android 第三篇( 依赖管理 )

    转自 https segmentfault com a 1190000004237922 依赖管理 这会是一个系列 所以如果你还没有看我之前的几篇文章 请先查看以下文章 Gradle for Android 第一篇 从 Gradle 和 A
  • 【论文精读】QLORA: Efficient Finetuning of Quantized LLMs

    QLORA Efficient Finetuning of Quantized LLMs 前言 Abstract Introduction Background Block wise k bit Quantization Low rank
  • element的嵌套dialog,在打开第二个dialog的时候会被遮罩层遮住

    element嵌套dialog遮罩层的问题 做项目的时候遇到一个问题 在一个弹出层的内容区做处理打开另一个弹出层时 第二个弹出层会被遮罩层遮住 点击五次之后遮罩层关闭 然后才发现 element 的dialog嵌套问题 之所以第二次弹出的会
  • 华为OD机试真题 Java 实现【区块链文件转储系统】【2023Q2 200分】,附详细解题思路

    一 题目描述 区块链底层存储是一个链式文件系统 由顺序的N个文件组成 每个文件的大小不一 依次为F1 F2 Fn 随着时间的推移 所占存储会越来越大 云平台考虑将区块链按文件转储到廉价的SATA盘 只有连续的区块链文件才能转储到SATA盘上
  • 安全基础 --- JSON + 函数声明

    JSON 格式 JSON JavaScript Object Notation缩写 是一种用于数据交换的文本格式 目的是取代繁琐笨重的 XML 格式 1 规定 复合类型的值只能是数组或对象 不能是函数 正则表达式对象 日期对象 原始类型的值