4.1 对属性的精细化设置
- 通过Object.defineProperty对属性进行添加与修改。
- Object.defineProperty()方法会直接在对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
接收参数:
- obj要定义属性的对象
- prop要定义或修改的属性名称或Symbol
- descriptor要定义或修改的属性描述符
返回值:
- 被传递给函数的对象
<script>
let obj = {
name: 'wc'
}
// 添加age属性
Object.defineProperty(obj, 'age')
// 重新添加name属性,就会把之前的name属性覆盖掉
Object.defineProperty(obj, 'name')
</script>
数据描述符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eilukreT-1659688174629)(C:\Users\fengli\AppData\Roaming\Typora\typora-user-images\image-20220723091740115.png)]
<script>
let obj = {
name: 'wc'
}
// 添加age属性
let newObj = Object.defineProperty(obj, 'age', {
value: 100, // 赋值
writable: true, // 默认false,不能修改属性
enumerable: true, // 默认false,不能被for in遍历
configurable: true,// 默认false,不能被delete删除
})
</script>
存取描述符
<script>
let obj = {
name: 'wc',
age: 18,
// 如果属性以_开头,潜规则表示这个是私有属性,不想被外界访问
_address: 'bj'
}
// 给obj上添加address属性
Object.defineProperty(obj, 'address', {
enumerable: true,
configurable: true,
// 当访问address时,自动调用get
get: function () {
console.log('get....');
return this._address
},
// 当给address设置值时,自动调用set
set: function (value) {
console.log('set....');
this._address = value;
}
})
console.log(obj['address']);
obj.address = 'sh';
console.log(obj['address']);
</script>
同时对多个属性进行定义
<script>
let obj = {
name: 'wc',
}
Object.defineProperties(obj, {
age: {
configurable: true,
enumerable: true,
writable: true,
value: 100
},
score: {
configurable: true,
enumerable: true,
writable: true,
value: 88
},
})
</script>
获取对象的属性描述符:
- getOwnPropertyDesciptor
- getOwnPropertyDesciptors
<script>
let obj = {
_age: 18 // 不想别人访问
}
Object.defineProperties(obj, {
name: {
value: 'wc',
configurable: true,
enumerable: true,
writable: true,
},
age: {
configurable: true,
enumerable: true,
get: function () {
return this._age
},
set: function (value) {
this._age = value
}
},
})
console.log(Object.getOwnPropertyDescriptor(obj, 'age'));
console.log(Object.getOwnPropertyDescriptors(obj));
</script>
4.2 创建对象的几种方法
4.2.1 字面量的形式创建的对象
<script>
// 通过字面量的形式创建的对象
// 缺点:需要写大量的重复代码
let wc = {
name: 'wc',
age: 11,
height: 140,
eating: function () { console.log('eating'); },
running: function () { console.log('eating'); }
}
let xq = {
name: 'xq',
age: 13,
height: 160,
eating: function () { console.log('eating'); },
playing: function () { console.log('playing'); }
}
let z3 = {
name: 'z3',
age: 1,
height: 190,
playing: function () { console.log('playing'); },
coding: function () { console.log('coding'); }
}
</script>
4.2.2 工厂模式创建对象
<script>
// 有一个函数,这个函数就是用来产生对象
// 这个函数,叫工厂函数
// 缺点:wc,xq,z3都是对象,那它的类型都是Object
// 我们希望不同的对象有不同的类型
function createPerson(name, age, height, address) {
let p = {}
p.name = name;
p.age = age;
p.height = height;
p.address = address
return p
}
let wc = createPerson('wangci', 13, 10, 'bj')
let xq = createPerson('xiaoqiang', 17, 140, 'sq')
let z3 = createPerson('zhangsan', 10, 180, 'sq')
</script>
4.2.3 构造器创建对象
<script>
// 缺点:造成内存空间浪费
// wc xq z3都是对象 对应的类是Person
function Person(name, age, height, address) {
this.name = name;
this.age = age;
this.height = height;
this.address = address;
this.running = function () { console.log(this.name + 'running...'); }
}
let wc = new Person('wangci', 13, 10, 'bj')
wc.running();
let xq = new Person('xiaoqiang', 17, 140, 'sq')
let z3 = new Person('zhangsan', 10, 180, 'sq')
</script>