详解js创建对象的几种方式和对象方法


Posted in Javascript onMarch 01, 2021

这篇文章是看js红宝书第8章,记的关于对象的笔记(第二篇)。

创建对象的几种模式:

工厂模式:

工厂是函数的意思。工厂模式核心是定义一个返回全新对象的函数。

function getObj(name, age) {
  let obj = {}
  obj.name = name
  obj.age = age
  return obj
 }
 let person1 = getObj("cc", 31)

缺点:不知道新创建的对象是什么类型

构造函数模式:

通过一个构造函数,得到一个对象实例。
构造函数和工厂模式区别是:
1,构造函数函数体加了this
2,构造函数没有return
3,构造函数调用时,用new关键字

function CreateObj(name, age) {
  this.name = name
  this.age = age
 }
 let person1 = new CreateObj("cc", 31)
 console.log(person1)
 console.log(person1.constructor === CreateObj); // true
 console.log(person1 instanceof CreateObj); // true

关于构造函数的两个问题:

1,构造函数和普通函数唯一区别是调用方式。构造函数要用new关键字。如果不用new,则是往Global对象上加属性。下面例子中,CreateObj方法,往window对象上加了name和age属性

function CreateObj(name, age) {
  this.name = name
  this.age = age
 }
 CreateObj('cc', 10)
 console.log(window.name) // 'cc'

2,构造函数存在的问题: 构造函数体内的方法,每次创建一个实例,都会创建一遍。

person1.sayName( ) === person2.sayName( ) // false

解决方法是,将sayName定义在createObj外面。

function sayName() {
  console.log(this.name)
 }
 function CreatePerson(name, age) {
  this.name = name
  this.age = age
  this.sayName = sayName
 }
 let person1 = new CreatePerson('joy', 31)
 person1.sayName()

但是,这样会让自定义类型引用的代码不能很好聚在一起。

原型模式:

原理是,每个函数都有一个prototype属性。prototype是一个对象,里面定义的属性和方法会被所有实例共享。
关于原型模式,有两个等式:

function Person() { }
 let person1 = new Person()
 console.log(person1.__proto__ === Person.prototype)  // true
 console.log(Person.prototype.constructor === Person); // true

关于原型对象的三个方法:isPrototype , getPrototypeof,setPrototypeOf, Object.create()

// isPrototypeOf判断构造函数的原型对象是否是实例的原型对象
function Person() {}
 let person1 = new Person()
 console.log(Person.prototype.isPrototypeOf(person1)); // true
// 获取对象的原型对象
 function Person() {}
 let person1 = new Person()
 console.log(Object.getPrototypeOf(person1) === Person.prototype);
// 将某个对象,设为另一个对象的原型对象
 let person1 = {name: "cc"}
 let person2 = {age: 32}
 Object.setPrototypeOf(person1,person2)
 console.log(person1.name, person1.age); // cc 32
// 以某个对象为原型对象,创建一个新对象  
let person1 = {name: "cc"}
 let person2 = Object.create(person1)
 person2.age = 30
 console.log(person2.name, person2.age);

当访问一个对象person的name属性时,是按照以下步骤去访问:
1,person上如果有name属性(即便这个属性是null,也会返回null),返回name属性值;没有,继续去原型对象Person.prototype上找
2,如果原型上有name属性,返回原型上name属性值;没有,则返回undefined

判断一个属性是在实例上,还是在原型上,可以用hasOwnProperty

function Person() {}
 Person.prototype.name = "cc"
 let person1 = new Person()
 console.log(person1.name) // 'cc'
 console.log(person1.hasOwnProperty("name")); // false

判断一个对象上是否有个某个属性,用in操作符

// 对象自身 or 原型上找到,都返回true 
function Person() {}
 Person.prototype.name = "cc"
 let person1 = new Person()
 console.log("name" in person1) // true
 console.log(person1.hasOwnProperty("name")); // false

访问对象的属性的方法:

Object.keys( )
for ... in // 继承属性也会遍历出来
Object.getOwnPropertyNames(obj) // 会列出可枚举和不可枚举属性,其他和 Object.keys( )结果一样
Object.getOwnPropertySymbols(obj) // 和getOwnPropertyNames类似,只是仅针对symbol
Reflect.ownKeys(obj) // 和Object.keys( )结果一样

其他访问对象属性和属性值的方法:
Object.values( ) 对象值组成的数组,会省掉Symbol型。
Object.entries( ) 对象键值对组成的数组,会将键,转化成字符串,省掉Symbol型。

function Person() {}
 Person.prototype.name = "cc"
 let person = new Person()
 person.age = 21
 let sy = Symbol('sy')
 person[sy] = 'smile'
 console.log(Object.values(person)) // [ 21 ]
 console.log(Object.entries(person)) // [ [ 'age', 21 ] ]

到此这篇关于详解js创建对象的几种方式和对象方法的文章就介绍到这了,更多相关js创建对象内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
js textarea自动增高并隐藏滚动条
Dec 16 Javascript
hover的用法及live的用法介绍(鼠标悬停效果)
Mar 29 Javascript
jquery text(),val(),html()方法区别总结
Nov 04 Javascript
js实现倒计时时钟的示例代码
Dec 17 Javascript
兼容最新firefox、chrome和IE的javascript图片预览实现代码
Aug 08 Javascript
JS实现的新浪微博大厅文字内容滚动效果代码
Nov 05 Javascript
用js读写cookie的简单方法(推荐)
Aug 08 Javascript
浅谈JS函数定义方式的区别
Oct 30 Javascript
详解各版本React路由的跳转的方法
May 10 Javascript
解决node修改后需频繁手动重启的问题
May 13 Javascript
关于node-bindings无法在Electron中使用的解决办法
Dec 18 Javascript
在js文件中引入(调用)另一个js文件的三种方法
Sep 11 Javascript
vue 使用饿了么UI仿写teambition的筛选功能
Mar 01 #Vue.js
vue实现拖拽进度条
Mar 01 #Vue.js
vue 使用 v-model 双向绑定父子组件的值遇见的问题及解决方案
Mar 01 #Vue.js
js闭包和垃圾回收机制示例详解
Mar 01 #Javascript
vue前端和Django后端如何查询一定时间段内的数据
Feb 28 #Vue.js
vue-router路由懒加载及实现的3种方式
Feb 28 #Vue.js
vue-router懒加载的3种方式汇总
Feb 28 #Vue.js
You might like
php array的学习笔记
2012/05/10 PHP
PHP 将逗号、空格、回车分隔的字符串转换为数组的函数
2012/06/07 PHP
PHP 常用数组内部函数(Array Functions)介绍
2013/06/05 PHP
解析web文件操作常见安全漏洞(目录、文件名检测漏洞)
2013/06/29 PHP
php清空(删除)指定目录下的文件,不删除目录文件夹的实现代码
2014/09/04 PHP
php图片的二进制转换实现方法
2014/12/15 PHP
yii2 RBAC使用DbManager实现后台权限判断的方法
2016/07/23 PHP
javascript中运用闭包和自执行函数解决大量的全局变量问题
2010/12/30 Javascript
Javascript调用C#代码
2011/01/17 Javascript
JS阻止冒泡事件以及默认事件发生的简单方法
2014/01/17 Javascript
jQuery之ajax删除详解
2014/02/27 Javascript
javascript遇到html5的一些表单属性
2015/07/05 Javascript
微信小程序实战之自定义模态弹窗(8)
2017/04/18 Javascript
JS判断时间段的实现代码
2017/06/14 Javascript
React学习笔记之事件处理(二)
2017/07/02 Javascript
Bootstrap提示框效果的实例代码
2017/07/12 Javascript
搭建element-ui的Vue前端工程操作实例
2018/02/23 Javascript
原生js实现点击轮播切换图片
2020/02/11 Javascript
Vue自定义全局弹窗组件操作
2020/08/11 Javascript
vue-cli 关闭热更新操作
2020/09/18 Javascript
[48:00]EG vs LGD 2018国际邀请赛淘汰赛BO3 第二场 8.26
2018/08/29 DOTA
详解Python中的__new__()方法的使用
2015/04/09 Python
详解Python中for循环的使用
2015/04/14 Python
PyQt5打开文件对话框QFileDialog实例代码
2018/02/07 Python
python实现京东秒杀功能
2018/07/30 Python
关于Python 的简单栅格图像边界提取方法
2019/07/05 Python
CSS3制作圆形滚动进度条动画的示例
2020/11/05 HTML / CSS
html5 datalist 选中option选项后的触发事件
2020/03/05 HTML / CSS
美国精品家居用品网站:US-Mattress
2016/08/24 全球购物
美国领先的低折扣旅行网站:Hotwire
2019/01/19 全球购物
linux面试题参考答案(2)
2015/12/06 面试题
员工自我鉴定范文
2013/10/06 职场文书
军训自我鉴定
2013/12/14 职场文书
贷款承诺书范文
2014/05/19 职场文书
Android Rxjava3 使用场景详解
2022/04/07 Java/Android
mysql数据库隔离级别详解
2022/06/16 MySQL