秒懂JS创建对象的方式
发布日期:2022-02-22 16:04:46 浏览次数:12 分类:技术文章

本文共 4145 字,大约阅读时间需要 13 分钟。

一、创建单个对象实例

  1. 构造函数创建对象:var obj=new Object(); obj.属性名=属性值; 添加属性
  2. 对象字面量 obj{属性名:属性值,…}
  • 问题:使用一个接口创建很多对象,产生大量重复代码
  • 解决:工厂模式

二、工厂模式

  • 用函数封装接口创建对象的细节,调用函数创建多个对象。
function createPerson(name, age, job) {
   
var obj = new Object();
obj.name = name;
obj.age = age;
obj.job = job;
obj.sayname = function() {    
console.log(this.name);
}
return obj; //创建一个新对象,将对象返回
}
var obj1 = createPerson('张三', 20, '软件工程师');
var obj2 = createPerson('李四', 22, '软件工程师');
  • 问题:不能做到函数复用

三、构造函数模式

  • 构造函数首字母大写
  1. 使用new 创建对象,没有显式创建对象
  2. 构造函数的作用域赋值给新对象,this指向这个新对象,直接将属性和方法赋值给this
  3. 构造函数中,不写return语句 或 return 基本类型; 会将this作为返回值。 return对象; 会将对象作为返回值
function Person(name, age, job) {
   
this.name = name;
this.age = age;
this.job = job;
this.sayname = function() {    
console.log(this.name);
}
}
var obj3 = new Person('张三', 20, '软件工程师');
var obj4 = new Person('李四', 22, '软件工程师');
console.log(obj3.sayname==obj4.sayname);//false

使用new 操作符调用构造函数创建实例的过程

  1. 创建一个新对象
  2. 将构造函数作用域赋值给新对象,this指向新对象
  3. 执行构造函数中的代码,为新对象添加属性
  4. 返回新对象 return this;

构造函数作为普通函数 直接调用是给window添加属性和方法

构造函数模式的缺点

  • 每个方法都要在每个实例上重新创建一遍。因为方法(函数)是对象,每定义一个方法,就是实例化了一个对象。
  • 解决:原型模式

四、原型模式

  • 每个函数都有原型属性prototype ,是一个指针,指向函数的原型对象
  • 原型对象,可以让所有对象实例共享所有它所包含的属性和方法。
  • 原型模式创建对象: 在原型上添加属性和方法 Person.prototype.属性名=‘属性值’
function Person() {
   //构造函数
}
// 在原型上添加属性和方法
Person.prototype.name = '张三';
Person.prototype.age = '21';
Person.prototype.job = '前端攻城狮'
Person.prototype.sayName = function() {    
console.log(this.name);
}
//必须先重写原型再创建实例对象
var person1=new Person();
var person2=new Person();
console.log(person1.sayName==person2.sayName);//true  引用同一个方法

原型、构造函数 、实例的关系

  • 实例对象的constructor属性指向构造函数。person.constructor == Person

  • 构造函数原型对象的constructor属性指向该构造函数。Person.prototype.constructor==Person

  • 构造函数的prototype属性指向构造函数的原型对象(简称原型)

  • 构造函数与原型之间类似双向链表的关系

  • 实例对象的__proto__ 属性直接指向构造函数的原型对象。兼容性:safari,firefox,chrome可以使用
    person.__proto__==Person.prototype

  • 构造函数和实例的关系: 实例 instanceof 原型链中的构造函数 返回true

  • 原型和实例的关系:

    1. 原型.isPrototypeOf(实例)方法判断对象之间是否存在原型关系,存在 返回true
    2. Object.getPrototypeOf(实例); 返回对象的原型。支持IE9+

原型链:当代码读取某个对象的属性时,从实例本身构造函数开始查找,如果没有找到,查找__proto__ 指向的原型对象。

自身属性和原型属性

  • 优先访问自身属性
  • 使用null清空自身属性,再次访问该属性时不能访问到原型上的同名属性。
  • 用delete删除自身属性,delete person.name; 会获取到原型属性。

区分自身属性和原型属性

  1. 实例.hasOwnProperty(‘属性’) 方法继承于Object
    • 检测一个属性存在于实例中还是原型中,在实例中,返回true
  2. ‘属性’ in 实例; in操作符 可以通过对象访问到给定属性时(无论是实例中还是原型中)返回true。

原型模式 使用对象字面量添加原型属性 的问题

问题一:使用单独的Person.prototype 添加属性时,会保留原型中自带的constructor属性。
使用对象字面量添加属性时 会重写原型对象 ,失去默认的constructor属性。原型指向新的内存空间。

  • 解决: 在原型里 手动添加 constructor属性 指向构造函数

问题二:先创建实例对象,再使用对象字面量添加原型属性时,不能使用原型中的属性和方法。

  • 原型指向新的地址,构造函数可以自动指向新的地址,而实例仍然指向旧的原型地址.
  • 解决:创建对象写在原型下面。

原型模式 自身的问题

  • 使用实例对象可以修改 原型中引用类型的属性,而这个属性被所有实例共享

五、组合使用构造函数 和 原型模式 —— 创建自定义类型的常见方式

  • 构造函数定义实例属性
  • 原型上定义方法和共享的属性
//属性写在构造函数里面,每个对象都有自己的属性
function Person(name, age, job){    
this.name = name;
this.age = age;
this.job = job;
this.friends=['lily','nacy'];//引用类型的属性值 
}
Person.prototype={
constructor:Person,
//方法写在原型里,实例可以共享
sayName:function(){    
console.log(this.name);
}
}
var person1=new Person('张三',29,'软件工程师');
var person2=new Person('李四',39,'医生');
person1.friends.push('tom');
//引用类型的属性值 不共享
console.log(person1.friends);//(3) ["lily", "nacy", "tom"]
console.log(person2.friends);//(2) ["lily", "nacy"]
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);
}
}
}
var obj1=new Person('lily',25,'后勤');
var obj2=new Person('nacy',25,'财务');
obj1.sayName();//lily
obj2.sayName();
console.log(obj1.sayName== obj2.sayName)//true  共享原型方法

七、寄生构造函数模式

  • 类似于 工厂模式+构造函数模式
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;
}
var obj=new Person('lily',25,'后勤');
obj.sayName();//lily

八、稳妥构造函数模式

  • 稳妥对象指没有公共属性,方法也不引用this的对象。适合在安全环境中使用
function Person(name, age, job){
   
var o=new Object();
// 可以定义私有变量和函数
var name='lily';
function otherFunc(){    
conosle.log('ok');
}
o.sayName=function(){    
console.log(name);
}
return o;
}
var obj=new Person3('lily',25,'后勤');
obj.sayName();//lily

转载地址:https://blog.csdn.net/Conradine_Lian/article/details/105278930 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:深入探究JS基本数据类型及其转换
下一篇:DOM文档对象模型(思维导图版)

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.67.49.205]2022年09月30日 08时16分38秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

最新文章