深入学习js之浅谈对象(对象的常见特性)

本文深入探讨JavaScript中的对象概念,包括7种主要数据类型、内置对象、属性访问方式的区别、对象复制方法、属性描述符及其特性等核心内容。

在js中一共有7中主要类型

string number boolean null undefined object symbol(ES6)

简单基本类型本身不是对象(除了object的类型)

typeof null 返回object是个语言BUG大家都懂


js的内置对象(对象子类型,object下的子类型)

String Number Boolean Object Function Array


1. .操作符和[]操作符的区别

.操作符要求满足标识符的命名规范

[".."]语法可以接受任意UTF-8/Unicode字符串作为属性名。

由于[]语法使用字符串来访问属性,所以可以在程序中构造这个字符串,比如说:

var myObject = {
	a:2
};

var idx;

idx = "a";

// 之后

console.log(myObject[idx]);

在对象中,属性名永远是字符串。如果你使用string(字面量)以外的其他值作为属性名,那它首先会被转换为一个字符串。即使是数字也不例外,虽然在数组下标中使用的的确

是数字,但是在对象属性名中数字会被转换成字符串,所以当心不要搞混对象和数组中数字的用法。

ES6增加了可计算属性名,用法如下

var pre = "foo";
var myObject = {
	[pre + "bar"]:"hello",
	[pre + "baz"]:"world"
};
myObject["foobar"];//hello
myObject["foobaz"];//world
2.复制对象(深拷贝和浅拷贝)

对于浅拷贝来说会复制原对象的值和引用。

ES6中定义了Object.assign()方法来实现浅拷贝,例子如下

function foo() {
	console.log("foo");
}
var myObject = {
	a : 2,
	foo: foo
}

var newObj = Object.assign({}, myObject);
newObj.a;//2
newObj.foo === foo;//true
对于深拷贝来说,除了复制myObject还会复制foo
var foo = {
	c:3
}
var myObject = {
	a: 2,
	b: foo
}
console.log(JSON.stringify(myObject));
var newObj = JSON.parse(JSON.stringify(myObject));
console.log(newObj);
newObj.a;//2
newObj.b === foo;//false,注意这里是地址比较,也就是说这里两个对象是独立的
这里要注意用序列化一个json字符串并且根据这个字符串解析出一个对象的方法无法解决循环引用和函数
3.对象的属性描述符

从ES5开始所有的属性都具备了属性描述符

Object.getOwnPropertyDescriptor(myObject, "a",{
	value: 2,
	writable: true,
	configurable:true,
	enumerable:true
});

myObject.a;//2
我们可以使用Object.defineProperty(..)来添加一个新属性或者修改一个已有属性
1.Writable 决定是否偶可以修改属性的值

2.Configurable 是否可配置(只要属性是可配置的就可以使用bject.defineProperty(..)来修改属性描述符)

有个例外:即使configurable:false还是可以把writable改为false

configurable:false表示该属性不可修改和不可删除

3.Enumerable 控制属性是否出现在枚举中(是否可枚举)

4.Getter和Setter

当你给一个属性定义getter、setter或者两者都有时,这个属性会被定义成“访问描述符”。对于访问描述符来说,JS会忽略它们的value和writtable特性,取而代之的是关心set和get以及configurable和enumerable特性

var myObject = {
	get a() {
		return this.$a;
	},
	set a(val) {
		this.$a = val + 1;
	}
};
myObject.a = 2;
myObject.a; //3
get和set须成对出现

5.属性的存在性

var myObject = {
	a: 2
};
var obj = Object.create(myObject);
obj.b = 3;
console.log(("a" in obj));
console.log(("b" in obj));
console.log(obj.hasOwnProperty("a"));
console.log(obj.hasOwnProperty("b"));
in会在[[prototype]]原型链上查找

hasOwnproperty只会在当前对象上查找

6.属性的遍历

for in会遍历所有可枚举属性

var myObject = {
	a: 2
};
var obj = Object.create(myObject);
obj.b = 3;
for (prop in obj) {
	console.log(prop);//b a
}
除了for inES6还 增加了for of用来遍历值(数组可以直接用,对象要定义iterator方法)

小结:

js中的对象有字面形式(var a = {})和构造形式(var a = new Array(..)),字面形式更常用

对象就是键值对的集合。可以通过.和[]来获取属性值、访问属性时实际上是调用内部的GET操作,如果没有的话查找原型[[prototype]]链

属性不一定包括值----它们可能是具备getter和setter的“访问描述符”。此外,属性可以是可枚举或者不可枚举的,这决定了是否在for in循环中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值