JavaScript对象类型Object

前言

系统学习JavaScript,由于有3年的java后端开发经验,并且有2年的JavaScript+Jquery开发经验,所以像编程语言的一些通用知识就直接跳过了,重点关注JavaScript的语言特性和常用库。

JavaScript对象类型 Object

对象属于一个复合的数据类型,在对象中可以封装多个不同类型的属性,比如 Number、string,函数,Object、数组等等。

在JavaScript中,String、Number、Boolean、Null、Undefined属于基本数据类型,Object属于引用对象类型。
JavaScript的变量都是存储在栈内存中,基本类型的值也是在栈内存中保存,值与值之间互相独立,修改一个变量不会影响到另外一个变量。
在这里插入图片描述

JavaScript的对象是在堆内存中存储的,每创建一个新对象,就会在堆内存中创建一个新空间,而变量是保存的是对象在堆内存中的内存地址(引用),如果两个变量指向的是同一内存地址,那么一个变量修改属性会影响到另外一个变量。
在这里插入图片描述
两个基本类型的比较,比较的是数值,而两个对象的比较,比较的是地址,如果两个对象一模一样但是内存地址不同,也会返回false。
在这里插入图片描述

对象的分类:
  • 内建对象:由ES标准中定义的对象,在任何的ES实现中都可以使用,比如Math、String、Number、Boolean、Function等等。
  • 宿主对象:由JS的运行环境提供的对象,目前来讲主要是浏览器提供的对象,比如BOM、DOM。
  • 自定义对象:由开发人员自己定义的对象。
创建自定义对象:

使用构造函数Object创建:

//创建一个对象
var obj1 = new Object();
console.log(obj1);
console.log(typeof obj1);
//往对象中保存数据
obj1.name = "yehaocong";
obj1.age = 26;
console.log(obj1)
//获取对象中的属性值
console.log(obj1.name)
console.log(obj1.age)

在这里插入图片描述
使用字面量创建对象:

var obj1 = {"id":"12345","pid":"54321"};
console.log(obj1);
console.log(typeof obj1);
//往对象中保存数据
obj1.name = "yehaocong";
obj1.age = 26;
console.log(obj1)
//获取对象中的属性值
console.log(obj1.name)
console.log(obj1.age)

在这里插入图片描述

获取和设置对象属性的两种方式:

var obj = new Object();
//第一种方式使用  obj.属性名 = 属性值;
obj.name = "liaoxiaoyan";
//第二钟方式使用  obh[属性名] = 属性值;
obj["age"]= "22";

//获取
console.log(obj.name);
console.log(obj["age"]);

在这里插入图片描述
两种方式的区别:
使用中括号的方式比较灵活,如果使用变量或者特殊符号作为属性名时,第一种方式会报错。
在这里插入图片描述
上面这种情况就需要用中括号的方式。
在这里插入图片描述
或者使用变量时,第一种方式也不支持。
在这里插入图片描述
在这里插入图片描述

函数也可以是对象的属性,如果一个函数作为对象的属性进行保存,那我们就称这个函数是这个对象的方法,调用这个删除就说调用这个对象的方法。

var obj = {
	name:"liaoxiaoyan",
	age:22,
	//定义方法
	printAtt:function(){
			//this属性后面会说明,这里就是代表obj对象的引用。
		console.log(this.name);
		console.log(this.age);
	}
};
//调用方法
obj.printAtt();

在这里插入图片描述
遍历对象的属性:

/**
语法
for (var 变量 in 对象){
	变量的值是属性名
}
*/

var obj = {id:123456,name:"yehaocong",age:26};
for(var attName in obj){
	//这里要用中括号取值,用小数点取不了变量的值
	console.log(attName + "=" + obj[attName]);
}

在这里插入图片描述

构造函数

在JavaScript中,构造函数与普通函数没有区别,构造函数就是一个普通的函数,唯一区别是调用方式的不同,也就是计算同一函数,一种调用方式是普通函数,另外一种是构造函数。
还有一个规范是构造函数通常使用大写字母开头,但不是强制。

//创建一个函数
var Person = function(){
	this.name="yehaocong";
	this.age=26;
};
//普通函数使用方式
var result1 = Person();
//构造函数使用方式
var result2 = new Person();
//使用Object构造函数构造一个对象
var result3 = new Object();
//返回undefined,因为以普通函数调用Person方法不返回值。
console.log(result1);
//返回一个Person对象,因为这个返回值是以构造函数方法调用Person方法的。
console.log(result2);
//返回一个Object对象
console.log(result3);

在这里插入图片描述

构造函数的执行流程:

  1. 立即创建一个新对象。
  2. 将函数中的this属性赋值给新创建的对象。
  3. 依次逐行执行函数中的代码。
  4. 返回this。

使用同一个构造函数创建的对象,我们称为一类对象,也将一类构造函数称为一个类。我们使用构造函数创建一个对象,这个对象称为这个类的实例。

使用instantceof可以判断一个实例是否属于某个类。

在这里插入图片描述
上图可以看出只有result2属于Person类的实例,但是result2也属于Object类的实例,原因是所有对象都是Object的后代,所以任何对象跟Object做instanceof判断都是返回true。

在构造函数中创建方法的弊端:
创建方式:
在这里插入图片描述
弊端,这样,每个对象都会创建一个printAtt函数对象,但是这个函数对象一个跟多个没什么区别,效果都是一样的,但是如果这样创建出来的每个对象都有一个独立的printAtt函数对象,这样会影响到资源利用和效率。
在这里插入图片描述
所以需要使用共享函数对象,可以把该函数对象创建在外部,然后方法里面只赋值函数对象的引用。
如下:
在这里插入图片描述
两个对象的printAtt属性比较相等返回true,所以使用的是同一个函数对象,没有创建多个。
但是,这个方法还是有弊端的,这样会污染全局区域的命名空间,比如如果全局区域刚好有个属性名为printAtt,这个判断就会把原有的属性覆盖,导致污染了全局区域的命名空间,后面使用原型对象配合使用最佳。

原型对象

我们所创建的每一个函数,解析器都会像函数中创建一个属性prototype,这个属性对应着一个对象,这个对象就是所谓的原型对象,如果函数作为普通函数使用prototype没有任何作用,当函数以构造函数的形式调用时,他所创建的对象都有一个隐含属性,指向改构造函数的原型,我们对象可以通过__proto__来访问他。如果使用函数来访问的话,需要使用prototype来访问。
在这里插入图片描述
原型按照java来讲,跟父类有点相似,而原型对象就有点像java的父类对象。
所有同一个类的实例都可以访问到这个原型对象,我们可以将对象中的共享内容,统一设置到原型对象中。
当我们访问对象的一个属性或者方法时,它会现在对象自身中寻找,找到就使用,找不到就会到对象的原型对象中寻找,找到就直接使用。
以后我们创建对象时,可以把这些对象共享的属性或者方法,统一设置到对象的原型对象中,这样就不用重复为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些功能了。

比如上面方法的改造,把共享函数放到原型对象中,即达到了共用,又不会污染全局作用域:
在这里插入图片描述
使用in可以检查对象中是否含有某个属性,但是这个如果对象本身没有,但是原型对象中有的话,也会返回true。
在这里插入图片描述
如果想在属性只存在于对象本身时才返回true,可以使用对象的hasOwnProperty()方法。
在这里插入图片描述
原型对象也是对象,所以他也有原型,如果我们需要一个对象的属性,会先在对象本身寻找,如果没找到,会到对象的原型对象中寻找,如果还没找到,再到对象的原型对象的原型对象中寻找,直到找到Object对象的原型对象为止,因为Object对象的原型对象没有原型对象。如果没找到就返回undefined。

所以可以理解为一般对象的原型就是Object,原型对象就是Object对象,所以一般对象只会找到原型对象的原型对象就会停止,这就有点继承的味道。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值