博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[写作中...]Js面向对象(2): 创建对象
阅读量:5903 次
发布时间:2019-06-19

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

目标

  • 理解对象
  • 创建对象实例
  • 理解Js中的继承

前言

在中了解到了两种最简单的创建对象的方式,本篇详细讨论Js中各种创建对象的方法。

创建对象

重点需要搞清楚构造函数模式原型模式组合使用两种模式的创建对象实例方法。(明白前两个其实大概就明白了如何组合使用)

1、工厂模式

工厂模式是一种广泛使用的设计模式, 创建对象的工厂模式,简单地理解就是new Object()创建对象的具体过程封装为一个函数

function CreatSomething(){    const o = new object();    o.propertyName1='value1';    o.propertyName2='value2';    ...    o.functionName=function (){        console.log(this.propertyName1);    }}复制代码

工厂模式存在的问题是,没有解决对象识别的问题(无法判断一个对象是由哪个函数实例化的),因此用的也不多,作为一个了解。

2、构造函数模式

2.1、普通构造函数模式

通过Js的一些内置对象可以创建对象实例,如ObjectArray等,也可以自定义构造函数,如:

funtion Something(val,num){    this.propertyName1=val;    this.propertyName2=num;    ...    this.functionName=function (){        console.log(this.propertyName1);    }}const something1=new Something('val1',21);const something2=new Something('val2',20);复制代码

与工厂模式的区别在于:

  • 可以不用显式地创建对象(原因是被new承包了) ...=new Object()
  • 属性方法赋给了this对象
  • 可以不return新对象

所以相比工厂模式,使用构造函数创建对象实例更简洁,高效。

那么,构造函数是如何将属性和方法赋给实例对象的呢?

关键在于:

  • new 操作符
  • 以及this指针、作用域等相关知识点,参考。

2.2、new操作符

对于new操作符,我觉得理解下其执行步骤,应该就清楚了

  • (1) 创建一个新对象
  • (2) 将构造函数的作用域赋给新对象(将this绑定到这个新创建的对象)
  • (3) 执行构造函数中的代码(将属性和方法添加到这个新对象)
  • (4) 返回该对象

补充:模拟一个new操作符的实现(建议了解清楚原型之后再回过头来看)

function myNew(func){    const objNull={};  //新对象    if (func.prototype !== null){        obj.__proto__=func.prototype;     }    const obj=func.apply(res,Array.prototype.slice.call(arguments,1));  //绑定this    if ((typeof obj === "object" || typeof obj === "function") && obj !==null){        return obj;    }    return objNull;    }复制代码

在StackOverflow查阅new的时候看到一个评论戳中笑点...

2.3、思考:构造函数创建对象实例存在的问题?

简单来说,构造函数的问题在其对象的方法上。

3、原型模式

3.1、理解原型对象

我们创建的每一个函数都有一个prototype指针,指向一个对象(即原型对象),包含由当前函数派生出的所有实例共享的属性和方法

当调用构造函数创建实例后,实例内部将会包含一个[[prototype]]指针(浏览器中的实现是__proto__),指向其构造函数的原型对象prototype

所以简单总结下,

  • 实例.__proto__=构造函数.prototype
  • 另外ES5中封装了一个方法,MDN建议使用这种方式来操作
    • Object.getPrototypeOf(实例)==构造函数.prototype
function Person(){...}const someone=new Person();someone.__proto__===Person.prototype                            //trueObject.getPrototypeOf(someone)===Person.prototype               //true复制代码

3.2、普通原型模式

function Person(){    }Person.prototype.property1=val1;Person.prototype.property2=val2;Person.prototype.funcName=function (){    console.log(this.property1)};const someone = new Person();someone.fucName()  // 输出val1复制代码

3.3、内置对象的原型

Object Array Date RegExp FUnction 基本包装类型Boolean Number String单体内置对象Global Math复制代码

3.4、思考:原型模式创建对象实例存在的问题?

对象中值为引用类型的属性会被各实例共享,也就是说在原型模式下,改变一个实例对象的 引用类型属性值会影响到其他所有实例对象。

4、组合使用构造韩式和原型模式

更多创建对象实例的方式

动态原型模式

寄生构造函数模式

稳妥构造函数模式

小结

此处应该有个小结,不过还没想好该写些什么。

水平有限,不准确的地方,欢迎指正。

参考:

  • 《JavaScript高级程序设计》
  • 《你不知道的JavaScript》

转载于:https://juejin.im/post/5c66416b518825622f12e309

你可能感兴趣的文章
Apache和PHP结合、Apache默认虚拟主机
查看>>
ccnp大型园区网实现思路解析
查看>>
awk中如何表示小写字母
查看>>
openstack组件使用的默认端口
查看>>
c语言简单版坦克大战(AllenEnemyTrank文件)
查看>>
Java私塾: 研磨设计之备忘录模式(Memento)
查看>>
dos命令行输入adb shell命令为什么报错
查看>>
Centos7 中修改sshd端口
查看>>
即时通讯工程师招聘那点事
查看>>
KVM真机服务器网卡调整,命令行创建虚拟机,LV快照虚拟机
查看>>
DOM相关知识总结
查看>>
Idea+maven+testNG+Selenium+ReportNG自动化框架搭建
查看>>
Set Matrix Zeroes
查看>>
操作系统计数器分析
查看>>
MHDD检测不到硬盘的解决办法
查看>>
dev devfs udev sysfs及关系
查看>>
HTML基础知识总结二
查看>>
SSM+PageHelper+jqGrid实现数据分页
查看>>
搭建docker 私有镜像仓库
查看>>
欧几里得算法求最大公约数和一些典型算法--来自<算法>一书的学习
查看>>