| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> JavaScript知识库 -> JS构造函数和原型链的个人理解(面向对象编程) -> 正文阅读 |
|
[JavaScript知识库]JS构造函数和原型链的个人理解(面向对象编程) |
对象创建按照一贯所说的那样,万物皆对象,也就是在JavaScript(以下简称JS)所有的引用数据类型都是对象 而对象,都是由构造函数创建的,也就是说,对象都是由函数创建的 使用new关键字加上一个函数名,就可以得到一个实例对象(箭头函数除外)
像代码段中所示,用new Object();就得到了一个对象的实例对象(对于第二行代码中的字面量创建,其实可以视为在隐性地调用一个new Object()函数) new Map()就能得到一个Map数据结构的实例对象 通过工厂函数进行进一步理解工厂函数 在现实生活中的工厂中,一般对于单个工厂而言,他生产出来的就是自己这个阶段意义上的成品,比如说制衣厂生产的是衣服,制造纽扣的工厂生产出来的就是纽扣(也许在整个生产链上面不是成品,但是对于自己的这一部分来说就是成品) 所以工厂函数的作用,就是用于对象创建,可以隐藏复杂的构建细节 工厂的特点是可以批量生产 以下模拟一个口红生产工厂
在这个函数中,创建一个对象 对象中的属性,(.colorNumber色号,.size尺寸等等)是口红这个类的属性 对象中的属性值,(Dior772,8CM等)是这一只口红的这些属性对应的属性值 其实是调用Lipstick这个函数,传入参数,然后在函数里面实现了对象的创建,最后返回这个对象,赋值给Dior772这个变量,也就是Dior772这个变量中存储的是一个对象,这个对象会随着实参的变化而产生变化 可以理解为一个口红生产工厂叫做Lipstick,然后它接到了来自品牌的订单,给了它原材料以及生产要求,生产要求之类的就是实参,然后这个工厂在自己的内部创建了一个生产链,用生产要求这些数据去把口红实例化,变成一个具象的口红,再返回自己这个生产链生产出来的东西,给到品牌方,品牌方给这个口红命名为Dior772,就是一个完整的过程 一些工厂函数比如document.createElement("div")就是创建了一个div标签 构造函数终于要讲到构造函数了 上文有提到,JS中所有的对象都是由构造函数创建的 而在面向对象编程语言(比如Java)中,对象是由类创建的 所以为了模拟后端语言的一些方法,我们这里JS中的构造函数可以被看做是类 在构造函数中,采用大驼峰命名法 像刚刚所说,构造函数的作用是用来创建对象,new这个关键字,作用是在堆中开辟一个存储空间,创建一个新对象,然后把地址存储到栈中 对于一个函数来说,它是普通函数还是构造函数,不取决于如何定义这个函数,而是取决于我们如何调用函数 调用函数的时候,如果函数名前面有关键字new,就说明这个函数作为一个构造函数使用(就想嘛,一个函数在我们定义的时候就已经存在了,那用new后面加一个函数是啥意思,不就是像创建数组创建对象一样,用这个函数创建一个新的东西,那这个东西既然是用和数组和对象一样的方式创建的,说明数据类型也一样,数组/对象都是对象,所以说就是这样子创建了一个新的对象) 值得注意的一点是, 如果这个函数是个普通的函数,那么它的函数体中的this指向的是调用者window 如果这个函数是作为构造函数,那么函数体中如果出现this指针,那么这个指针指向的是新创建的对象的地址(体现在控制台上的是构造函数)
从这一段代码可以看出来,实际上是构造函数在创建这个对象的时候,在堆里面开辟了新的空间,然后把地址返回出来,存到p里面,而this指针指向的也是这个空间的地址,所以在每次new Phone()的时候,它的this动态地指向当前的地址。那么当然a(存储这个地址)和p(存储这个地址)是相等的 私有属性的定义
这段代码就是说,在每次创建一个新的对象的时候,这个对象的地址所对应的空间中就会放一个属性f,属性值是"aaaa",而每次的新的地址都是不一样的,也就是说每个对象都独立地具有了这个属性和属性值,所以在第五行代码中,修改了foo这个对象中的属性值,不会影响到其他的foo1之类的,而只是修改了自己的空间中的属性值 下面这个可以更直观的感受到
那么同理,添加在this关键字上的方法叫做私有方法
最后三行代码,虽然this.ddl的函数体是一样的,但是因为this指向不一样,对比的时候拿出地址中的方法去比较,是false 公有属性添加在this关键字上的叫做私有属性,但是可能会造成资源浪费 所以使用到了prototype(原型对象) 原型对象是函数的一个子属性,所有的函数都具有这个属性 而每个原型对象都具有一个指针,叫做constructor, 首先抛开prototype和constructor两个单词的含义 函数 -> 函数.prototype? ?从这个点操作符就可以看出来,prototype是函数的一个属性 那么属性这个词的意思可以帮助我们理解逆向关系,只有一个函数存在了,才会进一步有它的属性,也就是说属性是从函数中来的,也就能够理解为什么prototype会有一个指针指向函数 对于函数.prototype? 译为原型对象,我是这样理解的,比如现在有一个电视剧里的角色,她有原型,原型呢就是一个现实生活中真实存在的人,那么可以认为这个角色她本身存在是有多个属性的,比如她的身高体重年龄性别,放在对象中更好理解一点
那么我们可以很清楚的看出来,为什么说原型是她的一个属性 那么反过来,constructor就是这个角色,因为有这个角色,才会有这个角色的属性(才会有原型这一说,否则这个人就只是这个人,不叫原型),直接讲的话就是说因为有函数,才会有函数的属性,所以constructor直译为建造者(例子可能不是很恰当,但是我只能想到这样了) 原型对象的作用是 存储构造函数实例对象的公有属性 如果函数不作为构造函数使用,原型对象将没有意义 原型对象中的所有属性,都可以被构造函数的实例对象所访问 也就是可以直接理解成,原型对象是实例对象的父级,里面可以访问到外面,外面不能访问到里面(原型对象是构造函数的属性,所以原型对象和构造函数是平级的,而实例对象是由构造函数创建的,所以实例对象是构造函数的子级,所以实例对象是原型对象的子级)
?那么图中的__proto__(左右各是两个下划线) 定义:__proto__属性是一个静态的指针,始终指向了当前对象构造函数的原型对象 JavaScript中所有的对象 都拥有一个 __proto__ 属性 对于实例对象b,很好理解,它的构造函数是function Baz,构造函数的原型对象就是Baz.prototype 对于function Baz,函数的本质也是对象,函数的构造函数也是函数,是function Function,那function Function的原型对象是Function.prototype 对于最上面的函数和函数.prototype,后者是一个原型对象,对象是由function Object构造的,所以prototype的构造函数是funciton Object,那么它的__proto__指针就指向function Object的原型对象,也就是Object.prototype 总体来说,就是从里往外,如果实例对象中有这个属性,就用这个,如果没有,往外出,去原型对象中找,如果还没有,再往外,去Object.prototype里面找,再没有,就undefined |
|
JavaScript知识库 最新文章 |
ES6的相关知识点 |
react 函数式组件 & react其他一些总结 |
Vue基础超详细 |
前端JS也可以连点成线(Vue中运用 AntVG6) |
Vue事件处理的基本使用 |
Vue后台项目的记录 (一) |
前后端分离vue跨域,devServer配置proxy代理 |
TypeScript |
初识vuex |
vue项目安装包指令收集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 4:16:42- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |