探究JavaScript:Array方法、原型链继承和JSON

news2024/11/22 21:47:20

目录

Array对象

构造函数

静态方法

Array.isArray()

实例方法

valueOf()

toString()

对象的继承

构造函数的缺点

prototype属性作用

原型链

 读取对象的某个属性的过程:

constructor属性

instanceof运算符

JSON

JSON优点:

JSON 对值的类型和格式有严格的规定。

JSON对象

JSON.stringify()【JS格式->JSON格式】

第一个参数

第二个参数

第三个参数

参数对象的 toJSON() 方法

JSON.parse()【JSON格式->JS格式】


Array对象

构造函数

Array是javaScript的原生对象,同时也是一个构造函数,可以用它来生成新的数组

静态方法

Array.isArray()

Array.isarray方法返回一个布尔值,表示参数是否为数组。他可以弥补typeof运算法的不足

例如:

    <script>
        var arr = [1, 2, 3];
        var a = typeof arr;
        var b = Array.isArray(arr)
        console.log(a, b);
    </script>

结果:

实例方法

valueOf()

valueOf方法是一个所有对象都拥有的方法,表示对该对象求值

不同对象的valueof方法不尽一致,数组的valueof放阿飞返回数组本身

例如:

    <script>
        var arr = [1, 2, 3]
        var arr_result = arr.valueOf()
        console.log(arr_result);
    </script>

结果: 

toString()

toString方法也是对象的通用方法

数组的toString方法返回数组的字符串形式

例如:

    <script>
        var arr = [1, 2, 3]
        var arr_result = arr.toString()
        console.log(arr_result);
    </script>

结果:

对象的继承

A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法。这对于代码的复用是非常有用的。

大部分面向对象的编程语言,都是通过“类”(class)实现对象的继承。传统JavaScript 语言的继承不通过 class,而是通过“原型对象”(prototype)实现(类==原型对象)

对象是类的具体化

构造函数的缺点

JS通过构造函数生成新对象,因此构造函数可以视为对象的模版。实例对象的属性和方法,可以定义在构造函数内部

例如:

    <script>
        function Cat(name, color) {
            this.name = name;
            this.color = color;
        }
        var cat1 = new Cat('大毛', '白色');

        cat1.name // '大毛'
        console.log(cat1.name);
        cat1.color // '白色'
        console.log(cat1.color);
    </script>

上面代码中,Cat函数是一个构造函数函数内部定义了name属性和color属性,所有实例对象(上例是cat1)都会生成这两个属性,即这两个属性会定义在实例对象上面。

结果:

问题的提出:同一个构造函数的多个实例之间,无法共享属性,从而造成了对系统资源的浪费

问题的解决:JavaScript的原型对象(prototype)

prototype属性作用

JavaScript 继承机制的设计思想就是,原型对象的所有属性和方法,都能被实例对象共享。也就是说,如果属性和方法定义在原型上,那么所有实例对象就能共享,不仅节省了内存,还体现了实例对象之间的联系。

js规定,每一个函数都有一个Prototype属性,执行一个对象

对于普通函数来说,该属性基本无用,但是对于构造函数来说,生成实例的时候,该属性会自动生成实例对象的原型。

例如:

function Animal(name) {
    this.name = name;
}
Animal.prototype.color = 'white';//为Animal原型对象添加一个属性white
var cat1 = new Animal('大毛');
var cat2 = new Animal('二毛');

cat1.color // 'white'
cat2.color // 'white'\
console.log(cat1.color, cat2.color);

上面代码中,构造函数Animal的prototype属性,就是实例对象cat1和cat2的原型对象。原型对象上添加一个color属性和方法miaomiao,结果,实例对象都共享了该属性和方法。

结果:

 

结果显示实例对象可以正常的使用原型对象的属性和方法

注意

只要修改了原型对象,变动就立即会体现在所有实例对象上

如果实例对象自身就有某个属性或者方法,它就不会再取原型对象寻找这个属性或者方法(即自身拥有的优先级大于原型对象的优先级)

原型对象的作用,就是定义所有实例对象共享的属性和方法。

原型链

JavaScript规定,所有对象都有自己的原型对象(prototype)。一方面,任何一个对象,都可以充当其他对象的原型;另一方面,由于对象也是对象,所以它也有自己的原型。因此就会形成一个“原型链(prototype chain)”:对象到原型,再到原型的原型……

原型链继承:原型对象定义一个属性

如果一层层地上溯,所有对象的原型最终都可以上溯到Object.prototype,即Object构造函数的prototype属性。也就是说,所有对象都继承了Object.prototype的属性。

Object.prototype的原型是null,null没有任何属性和方法,也灭有自己的原型,因此原型链的尽头就是null

 读取对象的某个属性的过程

读取对象的某个属性时,JavaScript 引擎先寻找对象本身的属性,如果找不到,就到它的原型去找,如果还是找不到,就到原型的原型去找。如果直到最顶层的Object.prototype还是找不到,则返回undefined。

覆盖:如果对象自身和它的原型,都定义了一个同名属性,那么优先读取对象自身的属性

注意:一级级向上,在整个原型链上寻找某个属性,对性能是有影响的。所寻找的属性在越上层的原型对象,对性能的影响越大。如果寻找某个不存在的属性,将会遍历整个原型链。

constructor属性

prototype对象有一个constructor属性,默认指向prototype对象所在的构造函数

constructor属性的作用是:可以得知某个实例对象,到底是哪一个构造函数产生的。

例如:

function F() { };
var f = new F();

a = f.constructor === F // true
b = f.constructor === RegExp // false
console.log(a, b);

结果:

 根据可以知道:constructor属性确定了实例对象f的构造函数时F而不是RegExp

instanceof运算符

instanceof运算符返回一个布尔值,表示对象是否为某个构造函数的实例

instanceof运算符的左边是实例对象,右边是构造函数。它会检查右边构造函数的原型对象(prototype),是否在左边对象的原型链上。

instanceof的原理是检查右边构造函数的prototype属性,是否在左边对象的原型链上。有一种特殊情况,就是左边对象的原型链上,只有null对象。这时,instanceof判断会失真。

例如:

var obj = Object.create(null);
typeof obj // "object"
obj instanceof Object // false

上面代码中,Object.create(null)返回一个新对象obj,它的原型是null。右边的构造函数Object的prototype属性,不在左边的原型链上,因此instanceof就认为obj不是Object的实例。这是唯一的instanceof运算符判断会失真的情况(一个对象的原型是null)

instanceof运算符的一个用处,是判断值的类型。

例如:

var x = [1, 2, 3];
var y = {};
x instanceof Array // true
y instanceof Object // true

 根据结果显示可以知道x为数组,y为对象

注意:instanceof运算符只能用于对象,不适用原始类型的值。

JSON

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

JSON优点

书写简单,一目了然;符合 JavaScript 原生语法,可以由解释引擎直接处理,不用另外添加解析代码。

每个 JSON 对象就是一个值,可能是一个数组或对象,也可能是一个原始类型的值。总之,只能是一个值,不能是两个或更多的值。

JSON 对值的类型和格式有严格的规定。

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

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

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

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

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

以下都是合法的 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;
}
} // 属性值不能使用函数和日期对象

注意:null、空数组和空对象都是合法的 JSON 值。

JSON对象

JSON对象是 JavaScript 的原生对象,用来处理 JSON 格式数据

它有两个静态方法:JSON.stringify()和JSON.parse()。

JSON.stringify()【JS格式->JSON格式】

第一个参数

基本用法:

JSON。stringify()方法用于将一个值转换为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.stringify({ name: "张三" })
// '{"name":"张三"}'

上面的各种类型的值都会被转换为JSON字符串

注意:对于原始类型的值,转换结果会带双引号“”

特别的:

a = (JSON.stringify('foo') === "fool")
b = (JSON.stringify('foo') === "\"foo\"")
console.log(a, b);

上面代码中,字符串foo被转换为了"\"“foo”\“”。这是因为还原的时候,内层的双引号可以让js引擎知道,这是一个字符串,而不是其他的类型

结果:

 如果对象的属性是undefined、函数或 XML 对象,该属性会被JSON.stringify()过滤。

如果数组的成员是undefined、函数或 XML 对象,则这些值被转成null。

如果是正则对象会被转成空对象。

第二个参数

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

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

例:

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

a = JSON.stringify({ a: 1, b: 2 }, f)
console.log(a);

上面代码中的f函数,接受两个参数,分别是被转换的对象的键名和键值。如果键值是数值,就将它乘以2,否则就原样返回。

结果:

第三个参数

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

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

例:

// 默认输出
a = JSON.stringify({ p1: 1, p2: 2 })
console.log(a);
// 分行输出
b = JSON.stringify({ p1: 1, p2: 2 }, null, '\t')
console.log(b);

上面例子中,第三个属性\t在每个属性前面添加一个制表符,然后分行显示。

结果:

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

参数对象的 toJSON() 方法

如果参数对象有自定义的toJSON()方法,那么JSON.stringify()会使用这个方法的返回值作为参数,而忽略原对象的其他属性

例:

var user = {
    firstName: '三',
    lastName: '张',

    get fullName() {
        return this.lastName + this.firstName;
    },

    toJSON: function () {
        return {
            name: this.lastName + this.firstName
        };
    }
};

a = JSON.stringify(user)
console.log(a);

上面代码中,JSON.stringify()发现参数对象有toJSON()方法,就直接使用这个方法的返回值作为参数,而忽略原对象的其他参数。

结果:

toJSON方法的一个应用是:将正则对象自动转换为字符串

因为JSON.stringify()默认不能转换正则表达式,但是设置了toJSON()方法以后,就可以转换正则对象了。

例:

var obj = {
reg: /foo/
};
// 不设置 toJSON 方法时
JSON.stringify(obj) 
//结果: "{"reg":{}}"
// 设置 toJSON 方法时
RegExp.prototype.toJSON = RegExp.prototype.toString;
JSON.stringify(/foo/) 
//结果: ""/foo/""
hacker 平替写法 绕弯的写法

上面代码在正则对象的原型上面部署了toJSON()方法,将其指向toString()方法,因此转换成 JSON 格式时,正则对象就先调用toJSON()方法转为字符串,然后再被JSON.stringify()方法处理。

JSON.parse()【JSON格式->JS格式】

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

例如:

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 // 张三

如果传入的字符串不是有效的 JSON 格式,JSON.parse()方法将报错。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/624038.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux防火墙学习笔记5

iptables规则匹配及动作&#xff1a; 规则&#xff1a;根据规定的匹配条件来尝试匹配每个流经此处的数据包&#xff0c;匹配成功&#xff0c;则由规则指定的处理动作进行处理。规则是由匹配条件和动作组成的。 iptables的规则匹配条件分类&#xff1a; 基本匹配条件&#xff…

STM32 EC200N-CN MQTT链接服务器开发实录

开发环境 硬件&#xff1a;STM32F091CBT6 、EC200N-CN模块板 、USB-TTL串口助手 软件&#xff1a;VS CODE 、 STM32CUBEMX、IAR 8.32 1.硬件设计 连接好EC200N-CN模块和单片机主板。 EC200N-CN模块设计时注意供电和IO电平转换。 EC200N-CN是低功耗的&#xff0c;其主串口…

宝藏达人 | 10年运营支招,一文看懂运营全套技能!

本期介绍的ProcessOn宝藏达人是爱吃小麦馒头&#xff0c;他在互联网领域担任运营官十年以上&#xff0c;有着丰富的业务实操经验和运营方法论。职场风雨历练中他接触过一些“会省钱”的老板&#xff0c;发现有的企业对运营这一职业并未足够重视&#xff0c;随便调个HR做运营经理…

linux中系统性能监测命令sar,查看cpu、内存、磁盘、网络等使用情况

显示系统CPU利用率的统计信息&#xff1a; sar -u 1 5 -u: 这是sar命令的选项之一&#xff0c;表示要显示CPU利用率相关的统计数据。1: 这是指定采样间隔的参数&#xff0c;表示每秒采样一次数据。5: 这是指定采样次数的参数&#xff0c;表示总共采样5次数据。 %user&#xf…

18.5:给定一个栈,请逆序这个栈,不能申请额外的数据结构,只能使用递归函数

给定一个栈&#xff0c;请逆序这个栈&#xff0c;不能申请额外的数据结构&#xff0c;只能使用递归函数 package algorithmbasic.class18;import java.util.Stack;//给定一个栈&#xff0c;请逆序这个栈&#xff0c;不能申请额外的数据结构&#xff0c;只能使用递归函数 publi…

网络安全为什么缺人? 缺什么样的人?

1.网络安全为什么缺人? 缺人的原因是有了新的需求。 以前的时候&#xff0c;所有企业是以产品为核心的&#xff0c;管你有啥漏洞&#xff0c;管你用户信息泄露不泄露&#xff0c;我只要做出来的产品火爆就行。 这一切随着《网络安全法》、《数据安全法》、《网络安全审查办法…

gaussdb的日期函数加减操作

日期加一天&#xff0c;四种写法&#xff0c;减一天换成减法- SELECT now() integer 1 SELECT date 2023-06-08 integer 1 SELECT timestamp 2023-06-08 integer 1 select 2023-06-08 ::date interval 1 day 日期加减一周&#xff0c; select 2023-06-08 ::date …

influxDB 1.8 笔记(更新中)

1、InfluxDB基本数据结构 数据结构含义database数据库measurement数据库中的表retention policy保存策略&#xff1a;让InfluxDB能够知道可以丢弃哪些数据&#xff0c;设置数据自动清除时间&#xff0c;从而更高效的处理数据points表里面的一行数据 points的数据结构 数据结…

Android实例——2048游戏

2048游戏 项目简介ConfigConstantsGameActivityGameItemGameViewMainActivityScreenUtils布局activity_game.xmlactivity_main.xml 项目简介 选择难度&#xff0c;生成随机数字&#xff0c;通关上下左右滑动&#xff0c;合并相同的数字&#xff0c;直到达到目标数字即可通关游…

MAC环境编译Android环境下的FFmpeg6.0版本

文章目录 一. 下载FFmpeg源码二、对FFmpeg进行安装编译三、进行JNI接口编写代码四、在Android 项目中调用.so库五、FFmpeg的代码学习技巧1、整体学习步骤2、FFmpeg的代码学习步骤 六、参考链接: 一. 下载FFmpeg源码 该项目是基于FFmpeg6.0环境编写。文中涉及代码在不同版本可能…

配置MySQL保存Hive元数据

Hive默认使用自带&#xff08;内嵌&#xff09;的Derby进行元数据存储&#xff0c;这个就意味着无法实现多个hive shell并发连接Hive。如果需要支持多用户登录Hive&#xff0c;必须配置一个独立的数据库。上一节我们已经将MySQL数据库安装到Linux上&#xff0c;本节我们将讲解一…

微服务架构基础--第1章认识微服务架构

第1章认识微服务架构 一.预习笔记 1.为什么需要微服务架构 传统的单体应用架构都是模块化的设计逻辑&#xff0c;易于开发和调试&#xff0c;也易于部署。但是随着用户量的增加&#xff0c;就无法满足系统的负载&#xff0c;虽然也可以进行单体架构的拓展&#xff0c;但是随着…

设备指纹系列--基础篇

基础概念 618还没开始&#xff0c;但是又好像已经结束了…在这种电商大促的大节日前&#xff0c;电商行业客户一般会提前找到合适的设备指纹产品&#xff0c;去防止被“薅秃”。因为&#xff0c;黑灰产拥有专业的设备牧场&#xff0c;通过使用模拟器、刷机改机等手段&#xff…

算法与数据结构-数组

文章目录 什么是数组线性表连续的内存空间和相同类型的数据 为什么数组的插入和删除是低效的插入删除 容器与数组的区别 什么是数组 数组&#xff08;Array&#xff09;是一种线性表数据结构。它用一组连续的内存空间&#xff0c;来存储一组具有相同类型的数据。 这个定义里有几…

Pytest自动化测试框架生成allure的报告

一、前言 最近通过群友了解到了allure这个报告&#xff0c;开始还不以为然&#xff0c;但还是逃不过真香定律。 经过试用之后&#xff0c;发现这个报告真的很好&#xff0c;很适合自动化测试结果的展示。下面说说我的探索历程吧。 选用的项目为Selenium自动化测试Pytest框架实…

IntelliJ IDEA彻底删除

我们在用idea的时候&#xff0c;idea的环境出现了莫名其妙的问题&#xff0c;怎么也找不到问题原因的时候可以试着把idea卸载重新安装。但是如果你卸载的时候没有删除干净注册表里的信息。就算再次安装回来也还是解决不了问题。 如何删除干净IDEA 将所有jetbrains软件关闭退出…

嵌入式软件工程师招聘

当您招聘嵌入式软件工程师时&#xff0c;以下是一些建议和关键要点&#xff0c;可以帮助您吸引和筛选合适的候选人&#xff1a; 职位描述&#xff1a;清晰地定义嵌入式软件工程师的职责和要求。包括对硬件和软件开发经验的要求、熟练掌握的编程语言&#xff08;如C、C、Python等…

一文学会MoveIt Setup Assistant搭建moveit2机械臂模型

文章目录 前言一、MoveIt Setup Assistant 是什么&#xff1f;二、搭建步骤拉取相关repo创建项目文档编辑moveit_description文件夹编辑moveit_config文件夹 MoveIt Setup Assistant 配置Launch moveit_setup_assistant配置干涉关系配置planning groups配置ros2 controller配置…

一个 TCP 连接可以发送多少个 HTTP 请求

第一个问题 第二个问题 第三个问题 第四个问题 第五个问题 曾经有这么一道面试题&#xff1a;从 URL 在浏览器被被输入到页面展现的过程中发生了什么&#xff1f; 相信大多数准备过的同学都能回答出来&#xff0c;但是如果继续问&#xff1a;收到的 HTML 如果包含几十个图…

优质高效!阿里内部超高质量的k8s+Jenkins笔记,技术与实战齐飞

什么是k8s? Kubernetes是一个用于容器集群的自动化部署、扩容以及运维的开源平台。 k8s孕育的初衷是培育出一个组件及工具的生态&#xff0c;帮助大家减轻在公有云及私有云上运行应用的负担&#xff0c;换言之&#xff0c;使得大型分布式应用的构建和运维变得更加简单&#…