我们来实现创建JavaScript中的自定义对象

本文详细介绍了JavaScript中的对象创建、构造函数、对象字面量、this关键字、内存管理、闭包以及JSON的使用。重点讲解了对象的三种创建方式,包括使用Object、构造函数和对象字面量,并通过实例展示了this的多种场景应用,以及闭包在内存保留和函数作用域中的作用。同时,还探讨了JSON作为数据交换格式的基本用法和转换操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

来来来,JavaScript核心基础语句送给你们
学JS你不会DOM算真的学会了吗?
对JavaScript中的 事件 进行疯狂 处理
用BOM来实现轮播图效果
我们来实现创建JavaScript中的自定义对象
JS中构造函数的原型prototype
还不明白JS中的内置对象吗? 快来这里!
JavaScript中数据如何存储在客户端?带你看看Cookie和WebStorage

自定义对象

1. 简介

什么是对象:

  • 万物皆对象,如手机、电脑、汽车、坐姿、学生、猫、狗等
  • 实现世界中充满了对象,符合人们的思维习惯

对象具有特征和行为:

  • 特征:对象具有的属性,如学生的姓名、年龄等
  • 行为:对象具有的能力,如学生可以学习、跑步、做自我介绍

JavaScript是基于对象的语言

  • 对象具有的特征,称为属性
  • 对象具有的行为,称为方法
2. 创建对象

三种方式:

  1. 使用Object
//1.创建对象
var 对象名 = new Object();
//2.为对象添加属性
对象名.属性名 = 属性值;
//3.为对象添加方法
对象名.方法名 = function(){
	方法体
}
//4.调用属性和方法
对象名.属性名; 或 对象名['属性名'];
对象名.方法名; 或 对象名['方法名']();
<script>
	//1.创建对象
	var stu = new Oject();
	//2.为对象添加属性(特征)
	stu.name = 'tom';
	stu.age = 27;
	stu['exam-score'] = 99;		//对于特殊的属性名,需要使用中括号[]方式来定义
	stu[24] = '科比';
	//3.为对象添加方法
	stu.study() = function(){
		console.log('学习');
	}
	stu.run() = function(){
		console.log('跑步');
	} 
	stu.show() = function(){
		console.log('我叫'+stu.name+',年龄,'+this.age);
	}
	//4.调用对象的属性和方法
	console.log(stu.name,stu['name']);
	console.log(stu.age,stu['age']);
	console.log(stu['exam-score']);
	console.log(stu[24]);

	stu.study();
	stu.run();
	stu.show();
</script>
  1. 使用构造函数

    用来创建对象的函数,称之为构造函数或构造器,相当于自定义了一个类型

function 构造函数名(形参1,形参2){	//为了区别与普通函数,构造函数名建议首字母大写
	this.属性名 = 形参1;
	this.属性名 = 形参2this.方法名 = function(){
		方法体
	};
}
var 对象名 = new 构造函数(实参1,实参2);
//定义一个带参的构造函数
function Student(name,age){
	this.name = name;	//此处的this表示将来创建的对象
	this.age = age;
	this.study = function(){
		console.log('学习');
	}
	this.run = function(){
		console.log('跑步');
	}
	this.show = function(){
		console.log('我叫'+this.name+',年龄,'+this.age);
	}
}
var stu1 = new Student('tom',18);	//通过new的方式来调用构造函数
console.log(stu1.name,stu1.age);
stu1.show();

var stu2 = new Student('alice',27);
console.log(stu2.name,stu2.age);
stu2.show();
  1. 使用对象字面量

    多个属性之间以逗号隔开,属性名和属性值之间以冒号隔开

var 对象 = {
	属性名:属性值,
	属性名:属性值,
	方法名 = function(){
		方法体
	}
};
var stu = {
	name:'Zack';
	age:18;
	'exam-score':100;		//特殊名称必须用引号引起来
	study:function(){
		console.log('学习');
	}
	show:function(){
		console.log('我叫'+this.name+',年龄:'+this.age);
	}
}

console.log(stu.name,stu['name']);
stu.study();
stu.show();
3. 对象的使用
<script>
    //创建对象数组
    var stus = [
        {
            id:1001,
            name:'Tom',
            age:18
        },
        {
            id:1002,
            name:'Zack',
            age:18
        },
        {
            id:1003,
            name:'Bob',
            age:18
        },
    ];
    //对数组进行循环
    for(stu of stus){
        //对数组中的每个对象进行循环
        for(var key in stu){
            console.log(key);   //对象的属性
            //console.log(stu.key);   //不能通过stu.key来获取,会认为要获取名称为key的属性
            console.log(stu[key]);  //必须通过中括号的方式来获取属性
        }
    }
</script>
4. this关键字

this表示当前对象

  • 函数中的this,表示调用函数的当前对象
<script>
	var a = 8;
	function f1(){
		console.log(this);	//此处的this表示window,因为是由window调用
		//解决局部变量和全局标量同名的问题
		console.log('局部变量:',a);
		console.log('全局变量:',window.a);
		console.log('全局变量:',this.a);
	}

	f1();	//shenglve了window,实际的函数调用者就是window对象
	//window.f1();
</script>
  • 事件绑定的匿名回调函数中的this,表示事件源
<script>
	//事件绑定的匿名回调函数中的this,表示事件源
	window.onload = function(){
		document.querySelector('#btn').onclick = function(){
			console.log(this);	//此处的this表示事件源,即触发事件的目标元素
		}
	}
</script>
<body>
	<button id="btn">点我</btn>
</body>
  • 构造函数中的this,表示new出来的当前对象
<script>
	//构造函数中的this,表示将来new出来的对象
	var name='科比';
	function Student(name,age){
		this.name = '汤姆';	//此处的this表示当前对象,即将来创建出的对象
		this.age = age;
		console.log('局部变量(形参):',name);	//tom
		console.log('对象的属性',this.name);	//汤姆
		console.log('全局变量:',window.name);
	}
	var stu = new Student('tom',11);
	console.log(stu);
</script>
5. 栈内存和堆内存
<script>
	//基本数据类型:string、number、boolean、undefined、null
	var a = 5;
	var b = a;
	b = 8;
	console.log(a);	//5
	console.log(b);	//8
	
	//引用数据类型:Object、Array
	var stu1 = {
		name:'tom',
		age:18
	}
	var stu2 = stu1;	//将stu1的地址赋给stu2,即让stu2和stu1指向同一内存地址空间
	stu2.name='Zack';
	console.log(stu1.name);		//Zack
	console.log(stu2.name);		//Zack
</script>

通过这两个例子我们就可以看出,基本数据类型和引用数据类型变量之间赋值的情况是不一样的,这就是因为它们的存储方式不同。

  • 栈内存

    基本数据类型的变量和引用数据类型的变量的引用会存储再栈内存中,存取速度比较快

  • 堆内存

    引用数据类型的数据会存储再堆内存中,存取速度较慢。

6. 基本数据类型和引用数据类型作为函数参数
  • 基本类型作为方法的参数

    传递的是参数的值

  • 引用类型作为方法的参数

    传递的是参数的引用

//将基本数据类型作为参数,传递的是值
function f1(args){
	args = 8;	//再函数内部修改参数的值,不会影响外部变量
}
var a = 5;
f1(a);	//按值传递
console.log(a);

//将引用数据类型作为参数,传递的是地址
function f2(agrs){
	agrs.name='Alice';	//在函数内部修改参数的值,会映像外部变量
}
var stu1 = {
	name:'Tom',
	age:18,
	gender:'male'
}
f2(stu1);	//按引用传递
console.log(stu1);
7. 闭包

闭包是JS中特有的现象,如何理解闭包?

  • 在一个函数内部又定义了一个函数,这个定义在内部的函数,就是闭包。
  • 闭包就是能够读取其他函数内部变量的函数。
  • 闭包是在某个作用域内定义的函数,该函数可以访问这个作用域内的所有变量。
  • 从作用上来说,闭包就是将函数内部和函数外部连接起来的一座桥梁。

闭包的用途:

  • 在函数的外部,可以读取到函数内部的变量
  • 让变量的值始终保存在内存中(不会被垃圾回收器回收)
<script>
	//作用1:再函数的外部,可以读取到函数内部的变量
	function f1(){
		var n = 13;	//局部变量
		function f2(){	//这里的f2就是闭包
			return n;	//再内部函数f2中可以访问到外部函数f1中的局部变量
		}
		return f2;	
	}
	
	var fn = f1();
	var n = fn();	//此时可以读取到函数f1内部的变量
	console.log(n);
	
	//作用2:让变量的值始终保存在内存中(不会被垃圾回收期回收)
	function f1(){
		va n = 99;
		function f2(){
			console.log(n++);
		}
		return f2;
	}
	
	var fn = f1();
	fn();
	fn();	//函数执行多次都输出了连续的结果,说明f1函数中的局部变量n一直保存在内存中
</script>

由于闭包会使函数中的变量都被保存再内存中,内存消耗会比较大。

如果内部函数使用外部函数的变量,在外部函数执行完之前变量会有改变时,内部只能获取最后改变的值,无法获取定义时的值,就会产生闭包。

解决方式:

  1. 不在函数内部定义函数,将函数定义在外部,在函数内部调用
  2. 为元素附加属性,用来存储变量
  3. 使用let来定义变量
//我们希望点击每一个li时打印‘点击了第i个li的字段’,但是我们使用闭包时输出的都是‘点击了第6个li’,这就是使用闭包出现了问题。
<script>
	//出现问题
	function add(){
		for(var i=1;i<=5;i++){
			var li = document.createElement('li');
			li.innerText = 'li'+i;
			li.onclick = function(){
				//当点击li时在执行该回调函数中的代码,此时训话已经执行完
				console.log('点击了第'+i+'个li');		//输出“第6个”
			}
			document.getElementById('myul').appendChild(li);
		}
	}
	//解决方法一:不在函数内部定义函数,将函数定义在外部,在函数内调用
	function add(){
		for(var i=1;i<=5;i++){
			var li = createLi(i);
			document.getElementById('myul').appendChild(li);
		}		
	}
	function createLi(num){
		var li = document.getElement('li');
		li.innerText = 'li'+num;
		li.onclick = function(){
			console.log('点击了第'+num+'个li');
		}
		return li;
	}
	//解决方法二:为元素附加属性,用来存储变量
	function add(){
		for(var i=1;i<=5;i++){
			var li = document.getElementById('li');
			li.innerText = 'li'+i;
			li.num = i;		//设置属性
			li.onclick = function(){
				console.log('点击了第'+this.num+'个li');
			}
			document.getElementById('myul').appendChild(li);
		}
	}
	//解决方法三:使用let来定义变量
	function add(){
		//使用let声明变量,支持块级作用域,它所声明的变量所在的区域不会受外部影响,称为暂时性死亡
		for(let i=1;i<=5;i++){
			var li = document.createElement('li');
			li.innerText = 'li'+i;
			li.onclick = function(){
				console.log('点击了第'+i+'个li');		
			}
			document.getElementById('myul').appendChild(li);
		}
	}
</script>
<body>
	<button onclick="add()">添加</button>
</body>
8. JSON简介

JavaScript Object Notation 是一种轻量级的数据交换格式,用于表示JavaScript对象的一种方式。

采用与编程语言无关的文本格式,易于阅读和编写,同时也易于解析和生成。

(1)基本用法

语法:{"属性名":属性值,"属性名":属性值......}

注意:

  • JSON结构是由一系列的键值对所组成的,称为JSON对象
  • 属性名使用双引号引起来
  • JSON和对象字面量的区别:JSON的属性名必须加双引号,而对象字面量不用
(2) 创建JSON对象
//1.简单的JSON对象
var stu = {
	"name":"Jack",
	"age":18,
	"flag":true,
	"run":function(){	//JSON对象中一般不定义方法
		console.log('跑步');
	}
};
console.log(stu.name);

//2.符合属性,属性的值为JSON对象
var user = {
	"name":{
		"firstname":"李",
		"lastname":"明"
	},
	"age":20;
	"adress":{
		"province":"江苏""city":"南京",
		"district":"秦淮区"
	}
}
console.log(user.name.firstName);
console.log(user.address.city);

//3.JSON对象的集合
var stus = [
	{
		"id":1001,
		"name":"小明",
		"age":22
	},
	{
		"id":1002,
		"name":"小华",
		"age":20
	},
	{
		"id":1003,
		"name":"小张",
		"age":23
	}
]
//循环
for(var i=0;i<stus.length;i++){
	for(var key in stus[i]){
		console.log(key+'='+stus[i][key]);
	}
}
(3)JSON转换
  • JSON转换为字符串
var stu = {
	"id":1001,
	"name":"Tom",
	"age":18
}

var str = JSON.stringify(stu);
  • 字符串转换为JSON
var str = '{"id":1001,"name":"Tom","age":18}';

var obj = JSON.parse(str);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值