四 、对象的拓展

四 、对象的拓展

4.1 Object.preventExtensions 取消对象可拓展性

作用:

用于取消对象的可拓展性

1
2
3
4
5
6
7
8
9
10
11
12
13
// 定义对象
var obj = {
a: 1
}
// 对象默认是可以拓展的
obj.b = 2;
console.log(obj); // {a: 1, b: 2}

// 取消对象的可拓展性
Object.preventExtensions(obj);
// 尝试添加属性
obj.c = 3;
console.log(obj); // {a: 1, b: 2} // 添加失败 原因就是取消了obj的可拓展性,但仍可以修改或删除属性

U3Nfjx.png

总结

当取消了对象的可拓展性,仍然可以修改属性值,或删除属性

查看对象是否取消可拓展性:

Object.isExtensiable(obj) 返回值:true | false

1
2
// 查看对象的可拓展性是否被取消
console.log(Object.isExtensible(obj)); // false

4.2 Object.seal 封闭对象

作用:

用于封闭对象

1
2
3
4
5
6
7
8
// 定义对象
var obj = {
a: 1
}

// 封闭对象
Object.seal(obj);
// 封闭之后,对象可以被访问,不能拓展,不能删除,可以修改属性值

U3NIHO.png

总结

封闭之后,对象可以被访问,不能拓展,不能删除,可以修改属性值

查看对象是否被封闭:

Object.isSealed(obj); 返回值:true | false

1
2
// 查看对象是否被封闭
console.log(Object.isSealed(obj)); // true

4.3 Object.freeze 冻结

作用:

冻结对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 定义对象
var obj = {
a: 1
}
console.log(Object.isFrozen(obj)); // false

// 冻结对象
Object.freeze(obj);

// 添加属性
obj.b = 2;
// 修改属性
obj.a = 123;
// 删除属性
delete obj.a;

console.log(obj);
// 当对象冻结之后,不能拓展,不能删除,不能修改属性值

// 查看对象是否被冻结
console.log(Object.isFrozen(obj)); // true

U3NTED.png

总结

当对象冻结之后,不能添加属性,不能删除属性,不能修改属性值

查看对象是否被冻结:

Object.isFrozen(obj); 返回值:true | false

4.4 对象创建的新方式Object.create(prototype, options)

使用方式:

1
2
3
4
5
6
Object.create(prototype, options);
接收两个参数:
第一个参数是一个对像
该对象是Object.create创建出来的原型对象
第二个参数是一个对象
该对象是Object.create创建出来的特性对象

4.4.1 不传递参数

1
2
3
4
5
6
7
// 原有方式
var obj = {};
var obj1 = new Object();

// 使用 Object.create 创建对象
// 该方法接收两个参数: 第一个参数是原型对象, 第二个参数是特性对象
Object.create(); // 不传递传参数会报错

U3NvKP.png

4.4.2 参数为null

1
var obj2 = Object.create(null);

U3Nzb8.png

4.4.3 原型对象为null,特性对象正常添加

1
2
3
4
5
6
7
8
9
10
var obj3 = Object.create(null, {
color: {
value: "red",
writable: false
},
num: {
value: 200,
enumerable: false
}
});

U3U9Ug.png

4.4.4 只传递第一个参数且不为null

1
2
3
4
5
6
7
8
9
10
11
var obj4 = Object.create({
say: function(){
console.log("say");
},
sayHello: function(){
console.log("sayHello");
},
sayNihao: function(){
console.log("sayNihao");
}
});

U3UVK0.png

4.4.5 传递原型对象和特性对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 创建原型对象
var prototype = {
say: function(){
console.log("say");
},
sayHello: function(){
console.log("sayHello");
},
sayNihao: function(){
console.log("sayNihao");
}
}
// 创建特性对象
var options = {
color: {
value: "red",
writable: false
},
num: {
value: 200,
enumerable: false
}
}
var obj5 = Object.create(prototype, options);

U3UlG9.png

4.4.6 使用Object.create继承

4.4.6.1 使用类式继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// 定义父类
function People(name, age, sex){
this.name = name;
this.age = age;
this.sex = sex;
}

// 方法要写在原型上
People.prototype.sayHello = function(){
console.log("大家好,我的名字叫做:" + this.name + ";我的年龄是:" + this.age + ";我的性别是:" + this.sex);
}

// 定义子类
function Student(name, age, sex, grade){
// 构造函数式继承
People.apply(this, arguments);
this.grade = grade;
}

// 去掉 Student.Prototype 中多余的几个无用的属性 不可取:因为虽然能去掉,但是当多余的属性较多时,就不可能再逐一删除
// var p = new People();
// delete p.name;
// delete p.age;
// delete p.sex;

// 原本
// Student.prototype = {constructor: Student}
// 使用类式继承
Student.prototype = new People();

// 初始化对象
var s = new Student("小明", 12, "男", "六年级");
s.sayHello();
// s 是 Student的实例化对象, s 可以访问自身的属性
// 但是 Student.Prototype 中多余了几个无用的属性:name:undefined age:undefined sex:undefined
// 于是,Object.create 就出现了

U3UYqK.png

4.4.6.2 使用Object.create

只传递原型对象,不需要特性对象:

1
2
3
4
5
6
// 原本
// Student.prototype = {constructor: Student}
// 使用类式继承
// Student.prototype = new People();
// 使用Object.create
Student.prototype = Object.create(People.prototype);

U3U0Gd.png

4.4.7 模拟Object.create方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// 取消Object.create方法
Object.create = null;
// Object.create(null); // 报错,已经不是一个方法了
// 实现 Object.create 方法
Object.create = function(prototype){
var F = function(){

}
F.prototype = prototype;
return new F();
}





// 定义父类
function People(name, age, sex){
this.name = name;
this.age = age;
this.sex = sex;
}

// 方法要写在原型上
People.prototype.sayHello = function(){
console.log("大家好,我的名字叫做:" + this.name + ";我的年龄是:" + this.age + ";我的性别是:" + this.sex);
}

// 定义子类
function Student(name, age, sex, grade){
// 构造函数式继承
People.apply(this, arguments);
this.grade = grade;
}

// 想要让子类继承父类,需要使用类式继承,即原型式继承
// Student.prototype = new People();
// 参考:
// Student.prototype = People.prototype; // 不能直接这样用,会对原方法造成影响,但可作为参考
// var Fun = function(){

// }
// Fun.prototype = People.prototype;
// Student.prototype = new Fun();




var obj = Object.create(People.prototype);
Student.prototype = obj;



// 实例化对象
var s = new Student("小明", 12, "男", "六年级");
s.sayHello();

U3UfiQ.png

点击查看

本文标题:四 、对象的拓展

文章作者:Mango

发布时间:2020年07月14日 - 13:00:41

最后更新:2020年07月14日 - 13:27:10

原始链接:https://mango185.github.io/post/cbe6f8ca.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

-------------------本文结束 感谢您的阅读-------------------