发布于2021-05-30 12:20 阅读(1317) 评论(0) 点赞(27) 收藏(0)
简单的创建一个对象,可以使用Object构造函数,也可以直接使用字面量的方式。
let o = new Object();
let obj = {};
如果我们需要创建一些类似的对象,这样就会产生很多重复的代码。
过去的JavaScript中也没有类的概念,为此聪明的JavaScript程序员使用了很多模式来创建对象
function createPerson(name, age, job){
let o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
console.log(this.name);
}
return o;
}
这样可以创建多个功能相似的对象
let person1 = createPerson("yk", 18, "software engineer");
let person2 = createPerson("ykk", 12, "student");
但是这样做有些问题,就是创建出来的对象到底还是Object的实例,无法判断它到底是什么具体类的实例,所以采用构造函数模式来解决这个问题
优点:解决了创建多个相似对象时,代码的复用问题
缺点:使用工厂模式创建的对象,没有解决对象识别的问题
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function () {
console.log(this.name);
};
}
一样可以创建很多相似的对象出来
let person1 = new Person("yk", 18, "software engineer");
let person2 = new Person("ykk", 12, "student");
这里创建出来的属性和方法,都在实例对象中。也就是每次创建一个对象,都会将属性和方法在对象中重新创建一遍,对于方法来说,这样是有点重复的。因为很多方法功能是一样的,没有必要为每一个实例对象都创建一个方法。
console.log(person1.constructor === Person); // true
console.log(person1.__proto__ === Person.prototype); // true
console.log(person1 instanceof Person); // true
console.log(person1 instanceof Object); // true
优点:解决了工厂模式中对象类型无法识别的问题,并且创建自定义的构造函数意味着将来可以将它的实例标识为一种特定的类型
缺点:在使用构造函数创建对象时,每个方法都会在实例对象中重新创建一遍。
将属性和方法都放在构造函数的原型上,就可以让实例对象共享属性和方法,节约内存
function Person() {}
Person.prototype.name = "yk";
Person.prototype.age = 18;
Person.prototype.job = "student";
Person.prototype.sayName = function () {
console.log(this.name);
};
let person1 = new Person();
let person2 = new Person();
console.log(person1.sayName === person2.sayName); // true
由于原型链的存在,通过实例对象可以访问到原型对象上的属性和方法
console.log(Person.prototype);
console.log(Person.prototype.constructor === Person);
console.log(Person.prototype.__proto__ === Object.prototype);
console.log(Person.prototype.__proto__.constructor === Object);
console.log(Person.prototype.__proto__.__proto__ === null);
优点:解决了构造函数模式中多次创建相同函数对象的问题,所有的实例可以共享同一组属性和函数。
缺点:省略了构造函数模式传递初始化参数的过程,所有的实例在默认情况下都会取得默认的属性值,会在一定程度上造成不方便。
因为所有的实例都是共享一组属性,对于包含基本值的属性来说没有问题,但是对于包含引用类型的值来说(例如数组对象),所有的实例都是对同一个引用类型进行操作,那么属性的操作就不是独立的,最后导致读写的混乱。
我们创建的实例一般都是要有属于自己的全部属性的,因此单独使用原型模式的情况是很少存在的。
组合使用构造函数模式和原型模式
构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性。
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
}
Person.prototype.sayName = function(){
console.log(this.name);
}
let person1 = new Person("yk", 18, "software engineer");
let person2 = new Person("ykk", 12, "student");
person1.sayName(); // 'yk'
person2.sayName(); // 'ykk'
console.log(person1.sayName === person2.sayName); // true
优点:采用了构造函数模式和原型模式的优点,这种混成模式是目前使用最广泛,认同度最高的一种创建自定类型的方法。
缺点:由于使用了两种模式,因此对于代码的封装性来说不是很好。
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
if (typeof this.sayName !== "function") {
Person.prototype.sayName = function () {
console.log(this.name);
};
}
}
let person1 = new Person("yk", 19, "student");
person1.sayName(); // "yk"
注意在 if 语句中检查的可以是初始化后应该存在的任何属性或方法,不必要检查每一个方法和属性,只需要检查一个就行。
优点:解决了混成模式中封装性的问题
function Person(name, age, job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
console.log(this.name);
};
return o;
}
这个模式和工厂模式基本上是一样的,只不过我们是采用 new 操作符最后来创建对象。
注意在构造函数不返回值的情况下,默认会返回新创建的对象,而通过在构造函数的末尾添加一个 return 语句,可以重写调用构造函数时返回的值。
优点:可以基于一个已有的类型,在实例化时对实例对象进行扩展。这样既不用修改原来的构造函数,也达到了扩展对象的目的
缺点:不能依赖 instanceof 操作符来确定对象的类型
《JavaScript高级程序设计(第四版)》
JavaScript深入理解之对象创建
原文链接:https://blog.csdn.net/weixin_44972008/article/details/117223648
作者:小兔崽子
链接:http://www.qianduanheidong.com/blog/article/116126/52ba8f042e072711ce99/
来源:前端黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 前端黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-3
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!