当前位置: 首页 > ops >正文

创建对象

虽然Object构造函数或对象字面量可以方便地创建对象,但这些方式也有明显不足: 创建具有同样接口的多个对象需要重复编写很多代码  

1.工厂模式 

工厂模式是一种众所周知的设计模式,广泛应用于软件工程领域,用于抽象创建特定对象的过程 

function createPerson(name,age){let o=new Object(); o.name=name; o.age=age; o.sayName=function(){console.log(this.name);};return o;}let person1=createPerson('a',18);let person2=createPerson('b',19)

可以根据用不同的参数多次调用这个函数,每次都会返回2个属性和1个方法的对象,这种工厂模式虽然可以解决多个类似对象的问题,但没有解决对象标识问题(即新创建的对象是什么类型),每次创建对象的时候方法都会创建  

2.构造函数模式 

//第一种写法  
function Person(name,age){this.name=name; this.age=age; this.sayName=function(){console.log(this.name) };
}let person1=new Person("Nicholas",29);
let person2=new Person('b',27)//第二种写法 
let Person =function(name,age,job){this.name=name; this.age=age; this.sayName=function(){console.log(this.name) };
}//不传参数
function Person(){this.name="JaKe"; this.sayName=function(){console.log(this.name) };
}
let person1=new Person(); 
let Person2=new Person; 

Person()构造函数代替了createPerson()工厂函数,实际上Person()内部的代码跟createPerson()基本是一样的,只是有如下区别 

  • 没有显式地创建对象
  • 属性和方法直接复制给了this 
  • 没有return 

另外要注意按照惯例构造函数名称的首字母要大写,非构造函数则以小写字母开头,有助于区分构造函数和普通函数 

1.要创建Person的实例,应使用new操作符,使用new操作符会执行如下操作
  1. 在内存中创建一个新对象
  2. 这个新对象内部的[[prototype]]特性被赋值为构造函数的prototype属性 
  3. 构造函数内部的this被赋值为这个新对象(即this指向新对象)
  4. 执行构造函数内部的代码(给新对象添加属性)
  5. 如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象 

上个例子,person1和person2分别保存着Person的不同实例,这两个对象都有一个construcotr属性指向Person,如下所示 

conosle.log(person1.constructor==Person); //true  

console.log(person2.constructor==Person); //true 

instanceof操作符  用于判断一个对象是否是某个构造函数的实例 

console.log(person1 instanceof Object) //true   因为Person1是通过构造函数Person创建的,而Person.prototype最终继承自object.prototype 换句话说,所有对象的原型链最终都会指向Object.prototype 


console.log(person1 instanceof Person) 

2.1构造函数也是函数 

构造函数与普通函数唯一的区别就是调用方式不同,除此之外,构造函数也是函数,并没有把某个函数定义为构造函数的特殊语法,任何函数只要使用new操作符调用就是构造函数,而不是用new操作符调用的函数就是普通函数 

//作为构造函数

let person=new Person('a',17)

person.sayName(); 


//作为函数调用

Person("Greg",27); //添加到window对象 

window.sayName(); //"Greg"

//在领一个对象的作用域中调用

let o = new Object( ); 

Person.call(o,'Kristen',25)

o.sayName(); //"Kristen" 

2.2  构造函数的问题

构造函数虽然有用,但也不是没有问题,构造函数的主要问题在于,其定义的方法会在每个实例上都创建一遍,因此对前面的例子而言,person1和person2都有名为sayName()的方法,但这两个方法不是同一个Funtion实例,我们知道,js中的函数是对象,因此每次定义函数时,都会初始化一个对象

conosle.log(person1.sayName==person2.sayName); //false 

虽然可以把函数转移到构造函数外部,但是这样会搞乱全局作用域,这个新问题可以通过原型模式来解决 

3. 原型模式 (请看下面这篇文章)

js对象原型,原型链-CSDN博客

4.属性枚举顺序

for-in循环,Object.keys(),Object.getOwnPropertyNames(),Object.getOwnProperty-Symbols()以及Object.assign()在属性枚举顺序方面有很大区别,for-in循环和Object.keys()的枚举顺序是不确定的取决于js引擎,可能因浏览器而异 

Object.getOwnPropertyNames(),Object.getOwnpropertySymbols()和Object.assign()的枚举顺序是确定性的,先以升序枚举数值键,然后以插入顺序枚举字符串和符号键,在对象字面量中定义的键以它们逗号分隔的顺序插入 

let k1 = Symbol('k1'),k2 = Symbol('k2');let o = {1: 1,first: 'first',[k1]: 'sym2',second: 'second',0: 0
};o[k2] = 'sym2';
o[3] = 3;
o.third = 'third';
o[2] = 2;console.log(Object.getOwnPropertyNames(o));
// ["0", "1", "2", "3", "first", "second", "third"]console.log(Object.getOwnPropertySymbols(o));
// [Symbol(k1), Symbol(k2)]

5. 对象迭代 

1.Object.values() //返回对象值的数组
2. Object.entries() //返回健/值对的数组 
const o = {foo: 'bar',baz: 1,qux: {}
};console.log(Object.values(o));
// ["bar", 1, {}]console.log(Object.entries((o)));
// [["foo", "bar"], ["baz", 1], ["qux", {}]]注意: 非字符串属性会被转换为字符串输出,另外,这两个方法执行对象的浅复制: const o = {qux: {}
};console.log(Object.values(o)[0] === o.qux);
//true console.log(Object.entries(o)[0][1]=== o.qux); 
//true 符号属性会被忽略: 
const sym=Symbol(); 
const o={[sym]: 'foo'
}; 
console.log(Object.values(o));
// []
console.log(Object.entries((o)));
// []

http://www.xdnf.cn/news/6208.html

相关文章:

  • [Vue3]语法变动
  • 3D Gaussian Splatting 查看工具 splatviz
  • 案例 ss
  • linux-信号保存和处理
  • linux-进程信号捕捉
  • 继续预训练 LLM ——数据筛选的思路
  • Linux重定向与缓冲区
  • AI时代的弯道超车之第七章:如何用AI赋能创业?
  • 缺乏自动化测试,如何提高测试效率
  • 酒店旅游类数据采集API接口之携程数据获取地方美食品列表 获取地方美餐馆列表 景点评论
  • CodeBuddy Craft,我的编程搭子
  • element基于表头返回 merge: true 配置列合并
  • Oracle版本、补丁及升级(12)——补丁及补丁集
  • REVERSE学习笔记(攻防世界xxxorrr)
  • 【Java学习笔记】==运算符
  • 解决常见数据库问题:保障数据安全与稳定的全方位指南
  • 模板源码建站、定制建站和SaaS 建站有什么区别?企业建站应该怎么选?
  • C++引用编程练习
  • XILINX-DDR4-自定义componet(x8)-之一
  • 六西格玛觉醒:一场数据思维的启蒙运动​
  • 【江苏省】《信息技术应用创新软件适配改造成本评估规范》(DB32/T 4935-2024)-标准解读系列
  • 【Linux Nano Vim快捷键大全】
  • 基于EFISH-SCB-RK3576/SAIL-RK3576的康复训练机器人技术方案‌
  • Linux下批量提取子文件夹文件到当前目录
  • libmemcached库api接口讲解二
  • 股指期货套期保值怎么操作?
  • 【Linux】shell内置命令fg,bg和jobs
  • tensorflow安装及简单例程学习
  • 字符田字格绘制
  • Java的多线程笔记