JS基础_02—Object
- Object对象
- Object 静态方法
- create: 创建一个对象
- Object.defineProperty:定义对象属性,或修改一个对象的现有属性
- Object.defineProperties
- Object.keys:遍历可枚举的属性,只包含对象本身可枚举属性名称
- Object.values:遍历可枚举的属性值,只包含对象本身可枚举属性值
- Object.getPrototypeOf :获取指定对象的原型(内部[[Prototype]]属性的值)
- Object.setPrototypeOf :设置一个指定的对象的原型
- Object.getOwnPropertyNames :与keys相似,返回对象的所有`自身`属性的属性名(包括不可枚举属性但不包括symbol值作为名称的属性)组成的数组
- Object.getOwnPropertyDescriptor :获取该属性的描述对象
- Object.getOwnPropertyDescriptors :返回指定对象所有自身属性(非继承属性)的描述对象
- Object.is:它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致
- Object.hasOwnProperty:对象自身属性中是否具有指定的属性
- Object.isPrototypeOf
- Object.getOwnPropertySymbols
- Object.entries(obj)和for...in
Object对象
JavaScript中的对象其实就是一组数据和功能的集合。
通过new操作符后跟要创建的对象类型的名称来创建。
new:
从指定模具中复刻出一个一模一样的空间,此空间与外界隔离,视为实例。
由上可得new运算符就是进行创建空间
与外界隔离
后得到实例
的一个过程。
//创建一个Object对象
var o = new Object();
这里的Object相当于祖宗一样,创建Object的实例并没有什么用处。
特点:
每个Object类型的实例共有的属性和方法:
- constructor: 保存着用于创建当前对象的函数。
- hasOwnProperty:用于检测给定的属性在当前对象的实例中是否存在。
- isPrototypeOf : 用于检查传入的对象是否是当前对象的原型
- propertyIsEnumerble : 用于检查给定属性能否使用for-in来枚举
- toLocaleString() : 返回对象的字符串表示。
- toString() : 返回对象的字符串表示。
- valueOf() : 返回对象的字符串,数值,或布尔表示。通常和toString() 返回的值相同。
JavaScript中几乎所有的事物都是对象,比如我们的函数。
- Function
在javascript中,函数(Function)是一段被封装好的代码,可以被反复使用(调用);
函数可以是一个值、一个对象、一类数据,还可以是一个表达式,因此函数可以赋值、可以运算、可以拥有属性和方法,甚至可以临时存储值、构造实例等.
function 函数名(参数1,参数2,参数){ //注意,参数列表在函数中为局部变量
let a = 50;
let b = 100;
return a + b;// return 代表终止执行并将 a+b 计算结果返回给调用者。
a = 100; // 因为return的原因,该行代码不会执行。
}
在JavaScript中,对象内储存的内容其实就是以键值对的方式存在
如:{ A:“123” };
这里值得一提的是,我们对象中的每一个属性包括对象本身,都会有三个特性,如下所示:
/*
* 属性特性:
* configurable
* 当且仅当该属性的 configurable 键值为 true 时,该属性的描述符才能够被改变,同时该属性也能从对应* 的对象上被删除。简单来说,就是这个属性为flase的时候,就不能被删除
* enumerable
* 目标属性是否可被枚举(遍历),当且仅当该属性的 enumerable 键值为 true 时,该属性才会出现在对象的枚举属性中。
* writable
* 表示能否修改属性的值,即值是可写的还是只读。当且仅当该属性的 writable 键值为 true 时,属性的值,也就是上面的 value,才能被赋值运算符改变.
*/
Object 静态方法
create: 创建一个对象
const obj = Object.create({a:1}, {b: {value: 2}})
//第一个参数为对象,表示要继承的对象,是放在新对象的原型上的
//第二个参数用于对新创建的对象进行初始化,是放在新对象的实例上的(默认不能修改,不能枚举),
//即功能为:可以将生成的对象obj的原型指向第一个参数
obj.__proto__.a === 1 // true
obj.b = 3;
console.log(obj.b) // 输出还是2,即不可修改
for(let i in obj){console.log(i)}//输出a,即不可枚举
//创建一个可被修改的,可枚举的,可配置的属性p
obj2 = Object.create({}, {
p: {
value: 2, // 属性值
writable: true, // 是否可以重写值
enumerable: true, //是否可枚举
configurable: true //是否可以修改以上几项配置
}
});
obj2.p = 3;
console.log(obj2.p) // 输出3
for(let i in obj){console.log(i)}//输出p,即可枚举
注意: enumerable 会影响以下
for…in 遍历包括对象原型上属性
Object.keys() 只能遍历自身属性
JSON.stringify 只能序列化自身属性
Object.defineProperty:定义对象属性,或修改一个对象的现有属性
Object.defineProperty(object, prop, descriptor)
object:属性所在的对象
prop:属性的名字
descriptor:一个描述符对象
添加数据属性
var obj = {};
// 1.添加一个数据属性
Object.defineProperty(obj, "newDataProperty", {
value: 101,
writable: true,
enumerable: true,
configurable: true
});
obj.newDataProperty // 101
// 2.修改数据属性,第三个参数只传递要修改的部分就可以
Object.defineProperty(obj, "newDataProperty", {
writable:false
});
//3、添加get/set访问器属性,不能和value一同使用
var obj = {};
Object.defineProperty(obj, "newAccessorProperty", {
set: function (x) {
this.otherProperty = x;
},
get: function () {
return this.otherProperty;
},
enumerable: true,
configurable: true
});
注意: 1.第一个参数必须为对象
2.descriptor 不能同时具有 (value 或 writable 特性)(get 或 set 特性)。
3.configurable 为false 时,不能重新修改装饰器
Object.defineProperties
Object.defineProperties(object, {prop1 : descriptor1, prop2 : descriptor2, …)
var obj = {};
Object.defineProperties(obj, {
'property1': {
value: true,
writable: true
},
'property2': {
value: 'Hello',
writable: false
}
// etc. etc.
});
Object.keys:遍历可枚举的属性,只包含对象本身可枚举属性名称
let arr = ["a", "b", "c"];
let obj = { foo: "bar", baz: 42 };
let ArrayLike = { 0 : "a", 1 : "b", 2 : "c"};
Object.keys(arr) // ['0', '1', '2']
Object.keys(obj) // ["foo","baz"]
Object.keys(ArrayLike) // ['0', '1', '2']
Object.values:遍历可枚举的属性值,只包含对象本身可枚举属性值
let arr = ["a", "b", "c"];
let obj = { foo: "bar", baz: 42 };
let ArrayLike = { 0 : "a", 1 : "b", 2 : "c"};
Object.values(arr) // ["a", "b", "c"]
Object.values(obj) // ["bar",42]
Object.values(ArrayLike) // ["a", "b", "c"]
Object.getPrototypeOf :获取指定对象的原型(内部[[Prototype]]属性的值)
const prototype1 = {};
const object1 = Object.create(prototype1);//object1的原型是prototype1
console.log(Object.getPrototypeOf(object1) === prototype1); // true
注意:Object.getPrototypeOf(Object) 不是 Object.prototype
Object.getPrototypeOf( Object ) === Function.prototype; // true
Object.setPrototypeOf :设置一个指定的对象的原型
const obj = {a: 1}, proto = {b:2}
Object.setPrototypeOf(obj, proto)//将obj的原型设置为proto,和obj.__proto__ = proto等价
obj.__proto__ === proto //true
Object.getOwnPropertyNames :与keys相似,返回对象的所有自身
属性的属性名(包括不可枚举属性但不包括symbol值作为名称的属性)组成的数组
var my_obj = Object.create({}, {
getFoo: {
value: function() { return this.foo; },
enumerable: false
}
});
my_obj.foo = 1;
Object.getOwnPropertyNames(my_obj).sort() // ["foo", "getFoo"]
Object.getOwnPropertyDescriptor :获取该属性的描述对象
let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo')
// { value: 123, writable: true, enumerable: true, configurable: true }
Object.getOwnPropertyDescriptors :返回指定对象所有自身属性(非继承属性)的描述对象
Object.getOwnPropertyDescriptors 方法,返回指定对象所有自身属性(非继承属性)的描述对象。
const obj = {
foo: 123,
get bar() { return 'abc' }
};
console.dir(Object.getOwnPropertyDescriptors(obj))
// { foo:{ value: 123,
// writable: true,
// enumerable: true,
// configurable: true },
// bar:{ get: [Function: bar],
// set: undefined,
// enumerable: true,
// configurable: true }
// }
使用场景:
Object.assign() 方法只能拷贝源对象的可枚举的自身属性,同时拷贝时无法拷贝属性的特性,而且访问器属性会被转换成数据属性,也无法拷贝源对象的原型
Object.create() 方法可以实现上面说的这些,配合getPrototypeOf,以及getOwnPropertyDescriptors实现全面浅拷贝
Object.create(
Object.getPrototypeOf(obj),
Object.getOwnPropertyDescriptors(obj)
);
Object.is:它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致
Object.is('foo', 'foo') // true
Object.is({}, {}) // false
不同于 === 之处
+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
Object.hasOwnProperty:对象自身属性中是否具有指定的属性
方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性
let o = {a: 1 }
o.hasOwnProperty('a') //true
o.hasOwnProperty('b') //false 对象自身没有属性b
o.hasOwnProperty('toString'); //false 不能检测对象原型链上的属性
如何遍历一个对象的所有自身属性,例子:
var buz = {
fog: 'stack'
};
for (var name in buz) {
if (buz.hasOwnProperty(name)) {
console.log("this is fog (" + name + ") for sure. Value: " + buz[name]);
}
else {
console.log(name); // toString or something else
}
}
Object.isPrototypeOf
A.isPrototypeOf(B),方法用于测试A对象是否存在于另一个对象B的原型链上
function Foo() {}
function Bar() {}
function Baz() {}
Bar.prototype = Object.create(Foo.prototype);//Foo是Bar的原型
Baz.prototype = Object.create(Bar.prototype);//Bar是Baz的原型
var baz = new Baz();
console.log(Baz.prototype.isPrototypeOf(baz)); // true
console.log(Bar.prototype.isPrototypeOf(baz)); // true
console.log(Foo.prototype.isPrototypeOf(baz)); // true
console.log(Object.prototype.isPrototypeOf(baz)); // true
Object.getOwnPropertySymbols
var obj = {};
var a = Symbol("a");
var b = Symbol.for("b");
obj[a] = "localSymbol";
obj[b] = "globalSymbol";
var objectSymbols = Object.getOwnPropertySymbols(obj);
console.log(objectSymbols.length); // 2
console.log(objectSymbols) // [Symbol(a), Symbol(b)]
console.log(objectSymbols[0]) // Symbol(a)
Object.entries(obj)和for…in
Object.entries()方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用for…in循环遍历该对象时返回的顺序一致。区别在于for....in 会枚举原型链上的属性
。
var obj = function() {}
obj.prototype.zqx = 1;
var aaa = new obj()
aaa.zqx2 = 2;
console.log(Object.entries(aaa))
//只能获取到zqx2
console.log('----------')
for (i in aaa) {
console.log(i)
//可以获取到zqx和zqx2
}