Object相关方法
概述:
Object这个类是所有类的父类,也就是说它的方法和属性所有的对象都可以使用。Object的相关方法和属性是提供给其他的对象进行使用的。
相关方法和属性
原型方法及属性(实例方法及属性)
原型方法是对象实例使用的,由于Object是顶级父类,所有的对象都可以调用他的原型方法。
- hasOwnProperty(判断当前对象是否具备这个属性, 不会读取原型上的属性)
obj.hasOwnProperty (‘属性名’)
let obj = { name: 'jack' };
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sex = '男'
let person = new Person('tom', 18);
person.address = '湖南长沙'
// 判断当前对象是否具备属性 返回布尔类型的值 传入对应的需要判断的属性名
console.log(obj.hasOwnProperty('name')); //true
console.log(person.hasOwnProperty('age')); //true
// hasOwnProperty不会读取原型上的属性
console.log(person.hasOwnProperty('sex')); //false
console.log(person.hasOwnProperty('address')); //true
- isPrototypeOf 判断对象是否存在另一个对象原型链上
obj1.isPrototypeOf (obj2)
function Son() {
Person.call(this)
}
function Child() {
Son.call(this)
}
let person1 = new Person('rose', 19);
Son.prototype = person1;
let son = new Son();
Child.prototype = son;
let child = new Child();
console.log(person1.isPrototypeOf(son)); //true
console.log(son.isPrototypeOf(child)); //true
console.log(person1.isPrototypeOf(child)); //true
-
__defineGetter__
定义获取的方法 (废弃) -
__defineSetter__
定义设置的方法 (废弃) -
__lookupGetter__
返回定义的获取方法 (废弃) -
__lookupSetter__
返回定义的设置方法 (废弃)
// getter和setter的设置和查看 (实际操作的对象和访问的对象不能是同一个)
let obj1 = { name: "tom", age: 18 }
//存储对应obj1的值
let model = { name: "tom", age: 18 }
obj1.__defineGetter__('name', function () {
console.log('get触发了');
return model.name;
});
console.log(obj1.name);
obj1.__defineSetter__('name', function (v) {
console.log('set触发了');
model.name = v;
})
obj1.name = 'jack'
console.log(obj1.name);//jack
//查看get和set
console.log(obj1.__lookupGetter__('name')); //返回一个get函数
console.log(obj1.__lookupSetter__('name')); //返回一个set函数
- propertyIsEnumerable 判断当前属性是否可枚举
let obj = { name: "tom", age: 18 }
// propertyIsEnumerable 传入一个属性,判断这个属性的Enumerable属性的结果是什么
// Enumerable 可枚举 可以进行遍历
console.log(obj.propertyIsEnumerable('name')); //true
- toLocaleString 根据本地格式转为字符串
- toSting 转为字符串
Object.prototype.toString.call(需要查找的变量,(v)=>{这个v里面就有对应的类型})
// 转字符串
console.log(obj.toLocaleString()); //本地格式
console.log(obj.toString());
- valueOf 提取对应的value值
// valueOf 返回对应的值
console.log(obj.valueOf());
原型属性
- contructor 指向当前对象的构造函数
__proto__
对象隐式原型
静态方法(Object.方法调用的)
- Object.is 判断俩个对象是否是一个对象
Object.is(NaN,NaN)//true
- assign 将后面对象的内容拷贝到前面这个对象里面,返回前面这个对象中(浅拷贝)
let obj = { arr: [1, 2, 3] };
let obj1 = Object.assign(obj, { name: "rose" }, { age: 18 });
console.log(obj); //{arr: Array(3), name: 'rose', age: 18}
console.log(obj1 == obj);//true
// 对应的浅拷贝完成 (浅拷贝只拷贝第一层的值 第二层拷贝的都是地址)
let copyObj = Object.assign({}, obj)
console.log(copyObj);//{arr: Array(3), name: 'rose', age: 18}
console.log(copyObj == obj);//false
copyObj.arr.push(4);
console.log(copyObj.arr);//[1, 2, 3, 4]
- create 根据传入的内容创建相关的对象
// create方法
function Person() {
this.name = 'jack'
}
var person = new Person()
// 根据传入对象创建相关的对象 但是这个对象跟传入的对象不是同一个对象
// 他会将创建的对象的原型指向传入的对象
let createObj = Object.create(person);
console.log(createObj);
console.log(createObj == person); //false
console.log(person.isPrototypeOf(createObj)); //true
手写实现create
function myCreate(o) {
let newObj = new fn();
newObj.__proto__ = o;
return newObj;
}
let myCreateObj = myCreate(person);
console.log(myCreateObj);
- keys(将它的可枚举的key全部加入到一个迭代器返回)
- values ( 将它的value全部加入到一个迭代器返回)
- entries (将它的键值对全部加入到一个迭代器返回)
// keys values entries
let obj2 = { name: 'rose', age: 18, sex: '女' }
console.log(Object.keys(obj2));//['name', 'age', 'sex']
console.log(Object.values(obj2));//['rose', 18, '女']
console.log(Object.entries(obj2));//[['name', 'rose'],['age', 18],['sex', '女']]
- setPrototypeOf() 设置原型
- getPrototypeOf 获取原型
// setPrototypeOf() 设置原型
function Child(name) {
this.name = name;
}
let child = new Child('hh');
let proto = { address: '湖南', city: '长沙' }
Object.setPrototypeOf(child, proto)
console.log(child);
// getPrototypeOf 获取原型
let protoObj = Object.getPrototypeOf(child);
console.log(protoObj);
- freeze 冻结(只能查询)
- seal 密封 ( 能查询和修改,不能删除和添加新的属性)
- preventExtensions 不可扩展 (能查询,能修改,能删除,不能添加新的属性)
let obj = {
name: 'jack',
age: 18,
sex: '男'
}
//freeze冻结 只能查询
// Object.freeze(obj) //冻结当前的obj对象
// seal密封 能查询和修改
Object.seal(obj) //冻结当前的obj对象
console.log(obj.name);//查
obj.age = 20;//改
delete obj.sex;//删
obj.address = '长沙';//增
console.log(obj);
-
isFreeze
-
isSeal
-
isExtensible
等级划分:
freeze > seal > preventExtensions (冻结必定密封,密封必定不可扩展)
-
getOwnPropertyNames 获取所有的属性名(除symbol的key以外)
-
getOwnPropertySymbols 获取所有symbol为键的属性名
-
getOwnPropertyDescriptor 获取对应属性的详情(属性对象)
-
getOwnPropertyDescriptors 获取所有属性的详情 (对象)
let symbol = Symbol();
let obj = {
name: 'jack',
age: 18,
}
obj[symbol] = '你好';
// 获取所有的属性名(除了symbol的key以外) 传入的是一个对象 返回的是一个字符串数组
let name = Object.getOwnPropertyNames(obj);
console.log(name);
// 获取所有的symbol修饰的属性 获取所有symbol为键的属性 返回symbol数组
let symbols = Object.getOwnPropertySymbols(obj);
console.log(symbols);
// Descriptor getOwnPropertyDescriptor 获取属性的详情,返回是一个属性对象
let desc = Object.getOwnPropertyDescriptor(obj, 'name');
console.log(desc);
// Descriptor getOwnPropertyDescriptor 获取属性的详情,返回是一个属性对象
let descs = Object.getOwnPropertyDescriptors(obj);
console.log(descs);
属性对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vw17670F-1667484481354)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20221103161913502.png)]
- defineProperty 定义单个属性
// defineProperty的基础使用
let obj = {
name: 'rose'
}
// 基础的属性定义 传入对象 传入属性名 属性对象
Object.defineProperty(obj, 'age', {
configurable: false,//不写默认为false 是否可以删除
enumerable: false,//是否可枚举 是否可以被遍历
value: 18,//值
writable: true //是否可以修改
})
console.log(obj);
delete obj.age; //删除失败 因为configurable为false
console.log(obj);
// for in 只能遍历可枚举的属性
for (var key in obj) {//遍历失败
console.log(key);
}
obj.age = 30;
console.log(obj);//{name: 'rose', age: 30}
基础的属性定义
configurable:false,
enumerable:false,
value:18,
writable:false
访问器属性(已经存在的属性进行访问)
configurable:false,
enumerable:false,
get(){},//value
set(){}//writable
// 进行浅拷贝 操作一个对象(实际操作对象)
let obj = {
name: 'rose'
}
let model = Object.assign({}, obj)
Object.defineProperty(obj, 'name', {
onfigurable: true,
enumerable: true,
get() {
// 在访问的时候调用 替代了__defineGetter__
// 返回的值就是它对应获取的值
console.log('调用了get');
return model.name + '加工'
},
set(v) {
console.log('调用了set');
model.name = v
}
})
console.log(obj.name); //调用了get rose加工
obj.name = 'tom'; //调用了set
console.log(obj.name); //调用了get tom加工
- defineProperties 定义多个属性
let obj1 = {};
let model1 = {};
Object.defineProperties(obj1, {
username: {
onfigurable: true,
enumerable: true,
get() {
return model1.username
},
set(v) {
model1.username = v
}
},
password: {
onfigurable: true,
enumerable: true,
get() {
return model1.password
},
set(v) {
model1.password = v
}
}
})
obj1.username = '张三';
obj1.password = '123123';
console.log(obj1);
console.log(model1);
总结
- 原型方法重点:hasOwnProperty 、 isPropertypeOf
- Object是所有类的父类,所以他的原型方法及属性所有的类都拥有
- Object的静态方法是为所有的对象服务的,里面的参数都是对象
- defineProperty和观察者模式是Vue2的底层(实现Vue2的双向数据绑定))
面试题
for…in 和 Object.keys 和 Object.getOwnPropertyNames的区别
- for in 包含继承的属性及自身的属性(不包含不可枚举的属性)
- Object.keys 只包含自身的属性 (不包含继承和不可枚举的属性)
- Object.getOwnPropertyNames 只包含自身的属性 (不包含继承的属性,但包含不可枚举的属性)
- 三个都不包含symbol的属性
Property** 、 isPropertypeOf - Object是所有类的父类,所以他的原型方法及属性所有的类都拥有
- Object的静态方法是为所有的对象服务的,里面的参数都是对象
- defineProperty和观察者模式是Vue2的底层(实现Vue2的双向数据绑定))
面试题
for…in 和 Object.keys 和 Object.getOwnPropertyNames的区别
- for in 包含继承的属性及自身的属性(不包含不可枚举的属性)
- Object.keys 只包含自身的属性 (不包含继承和不可枚举的属性)
- Object.getOwnPropertyNames 只包含自身的属性 (不包含继承的属性,但包含不可枚举的属性)
- 三个都不包含symbol的属性