一、对象创建的四种方式以及区别
1.1、对象字面量
var dog1 = {
name: "大黄",
age: 2,
speak: function () {
console.log("汪汪");
},
};
1.2、使用Object构造函数
var dog2 = new Object();
dog2.name = "大黄";
dog2.age = 2;
dog2.speak = function () {
console.log("汪汪");
};
1.3、使用自定义构造函数
// 使用构造函数
function Dog(name, age) {
this.name = name;
this.age = age;
}
Dog.prototype.speak = function () {
console.log("汪汪");
};
var dog3 = new Dog("大黄", 2);
1.4、 使用Object.create
Object.create 用于创建一个新对象,使用现有的对象来提供新创建对象的原型对象。proto - 必须,新创建对象的原型对象。
prop - 可选,是一个对象,设置属性及属性值,默认值:undefined,(属性默认不能修改,不能枚举)。
语法:
Object.create(proto,prop)
创建一个原型为null的空对象
var o = Object.create(null);
console.log( o.__proto__ === undefined ); // true
创建一个原型为 { m: 1 } 的空对象
var a = { m: 1 };
var b = Object.create(a);
console.log( b.__proto__ === a ); // true
创建一个以空对象为原型对象,且拥有一个属性p的对象
var o = Object.create({}, { p: { value: 42 } });
console.log(o); // { p: 42 }
以字面量方式创建的空对象就相当于: Object.create(Object.prototype)
var o = {};
//相当于 var o = Object.create(Object.prototype)
console.log( o.__proto__ === Object.prototype ); //true
二、访问对象属性
2.1、以.
的方式访问
const obj = {
info: "wakaka",
inner: {
a: 10,
b: 20,
},
arr: [1, 2],
sayHi: (name) => {
console.log(`hi,${name}`);
},
};
// 用 dot(点 .) 的方式访问
console.log(obj.info); // wakaka
console.log(obj.inner); // {"a":10,"b":20}
console.log(obj.arr); // [1,2]
obj.sayHi("dengke"); // hi,dengke
2.2、以[]
的方式访问
// 用 [] 的方式访问
console.log(obj["info"]); // wakaka
console.log(obj["inner"]); // {"a":10,"b":20}
console.log(obj["arr"]); // [1,2]
obj["sayHi"]("dengke"); // hi,dengke
区别:
[]
中括号法:可以用变量作为属性名或访问,而点语法不可以;
var obj = {};
obj.name = "张三";
var myName = "name";
console.log(obj.myName); //undefined,访问不到对应的属性
console.log(obj[myName]); //张三
var person = {
name: "gogo",
};
console.log(person["name"]); //gogo
console.log(person.name); //gogo
// 优点:1,可以通过变量来访问属性
var propertyName = "name";
console.log(person[propertyName]); //gogo
var propertyName2 = "name2";
console.log(person[propertyName2]); //undefined
[]
中括号法:可以用数字作为属性名,而点语法不可以;
var obj1 = {};
// obj1.1=1;//Unexpected number
obj1[2] = 2;
// console.log(obj1.1)
console.log(obj1[2]); //2
// console.log(obj1.2)
console.log(obj1); //{2: 2}
[]
中括号法:可以动态设置和获取属性名,点操作符就不行;
// ( 即 []--可以动态设置和获取)
var customer = {};
var addr = ["北京", "上海", "广州", "深圳"];
for (i = 0; i < 4; i++) {
customer["address" + i] = addr[i];
}
console.log(addr);
console.log(customer);
- 如果属性名中包含会导致语法错误的字符,或者属性名是关键字或者保留字,也可以使用中括号表示法
person["first name"] = "gogo2"; //first name包含一个空格
console.log(person["first name"]);
// console.log(person.first name)//书写都通不过
person["for"] = "gogo_for"; //first name包含一个空格
person.if = "gogo_if"; //first name包含一个空格
console.log(person["for"]); //gogo_for
console.log(person.for); //gogo_for
console.log(person["if"]); //gogo_if
console.log(person.if); //gogo_if
补充
如果要访问的对象不存在,可以使用 逻辑运算符 || 指定默认值
只要“||”前面为false,不管“||”后面是true还是false,都返回“||”后面的值。
只要“||”前面为true,不管“||”后面是true还是false,都返回“||”前面的值。
可选链式操作符(?.) (es11)
这是当对象上没有这个键的时候,不会报错,而是赋值undefined
const foo = { name: "zengbo" };
let a = foo.name?.toUpperCase(); // "ZENGBO"
let b = foo.name?.firstName?.toUpperCase(); // "undefined"
三、删除对象属性
利用关键字 delete
const o = {
p: 10,
m: 20,
};
delete o.p;
console.log(o); // { m: 20 }
// 删除对象的属性后,在访问返回 undefined
console.log(o.p); // undefined
四、枚举对象的属性
for in
: 会遍历对象中所有的可枚举属性(包括自有属性和继承属性)Object.keys()
: 会返回一个包括所有的可枚举的自有属性的名称组成的数组Object.getOwnPropertyNames()
: 会返回自有属性的名称 (不管是不是可枚举的)
4.1、for…in…
会遍历对象中所有的可枚举属性(包括自有属性和继承属性)
const obj = {
itemA: "itemA",
itemB: "itemB",
};
// 使用Object.create创建一个原型为obj的对象 (模拟继承来的属性)
var newObj = Object.create(obj);
newObj.newItemA = "newItemA";
newObj.newItemB = "newItemB";
for (i in newObj) {
console.log(i);
}
// newItemA
// newItemB
// itemA
// itemB
// 现在我们将其中的一个属性变为不可枚举属性
Object.defineProperty(newObj, "newItemA", {
enumerable: false,
});
for (i in newObj) {
console.log(i);
}
// newItemB
// itemA
// itemB
4.2、Object.keys():
会返回一个包括所有的可枚举的自有属性的名称组成的数组
// 接上例
const result = Object.keys(newObj)
console.log(result) // ["newItemB"]
Object.keys()该方法在下文有更具体的介绍
4.3Object.getOwnPropertyNames()
会返回自有属性的名称 (不管是不是可枚举的)
// 接上例
const result = Object.getOwnPropertyNames(newObj)
console.log(result) // ['newItemA','newItemB']
五、Object常用的API
5.1、Object.assign()
语法
Object.assign(target, ...sources)
// 参数:target 目标参数,sources源对象 返回值:目标对象
Object.assign()
方法用于将所有可枚举属性的值从一个或多个源对象分配到目标对象。它将返回目标对象。常用来合并对象。
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 4, c: 5 };
const obj3 = Object.assign(obj1, obj2);
const obj4 = Object.assign({}, obj1); // 克隆了obj1对象
console.log(obj1); // { a: 1, b: 4, c: 5 } 对同名属性b进行了替换 obj1发生改变是因为obj2赋给了obj1
console.log(obj2); // { b: 4, c: 5 }
console.log(obj3); // { a: 1, b: 4, c: 5 }
console.log(obj4); // { a: 1, b: 4, c: 5 }
注意:
如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。
Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象。
assign其实是浅拷贝而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。同名属性会替换。
const obj5 = {
name: "dengke",
a: 10,
fn: {
sum: 10,
},
};
const obj6 = Object.assign(obj1, obj5);
console.log(obj6); // { a: 10, b: 2, name: 'dengke', fn: {…}}
console.log(obj1); // {a: 10, b: 2, name: 'dengke', fn: {…}} 对同名属性a进行了替换
bject.assign
不会在那些source对象值为null
或undefined
的时候抛出错误。
5.2、Object.keys()
语法:
Object.keys(obj)
参数:obj要返回其枚举自身属性的对象。
返回值:一个表示给定对象的所有可枚举属性的字符串数组。
Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致。
与Object.values()相似,区别在于这个返回的是数据的属性就是key。接下来就会介绍Object.values()。
const arr = ["a", "b", "c"];
console.log(Object.keys(arr)); // ['0', '1', '2']
const obj = { 0: "a", 1: "b", 2: "c" };
console.log(Object.keys(obj)); // ['0', '1', '2']
const obj2 = { 100: "a", 2: "b", 7: "c" };
console.log(Object.keys(obj2)); // ['2', '7', '100']
注意
在
ES5
里,如果此方法的参数不是对象(而是一个原始值),那么它会抛出TypeError
。在ES2015中,非对象的参数将被强制转换为一个对象。
5.3、Object.values()
语法:
Object.values(obj)
参数:obj被返回可枚举属性值的对象。
返回值:一个包含对象自身的所有可枚举属性值的数组。
Object.values() 方法返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for...in循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。与Object.keys()相似,区别在于这个返回的是数据的值也就是value
const obj1 = { foo: "bar", baz: 42 };
console.log(Object.values(obj1)); // ['bar', 42]
const obj2 = { 0: "a", 1: "b", 2: "c" };
console.log(Object.values(obj2)); // ['a', 'b', 'c']
注意
对象key
为number
的话,会从升序枚举返回。
const obj3 = { 100: 'a', 2: 'b', 7: 'c' }
console.log(Object.values(obj3)) // ['b', 'c', 'a']