前端学习第九周-函数执行,执行上下文,闭包,面向对象编程,new关键字,深浅拷贝,对象继承


前言

本周做了五子棋项目,对之前的学习进行实操

一、函数执行

函数执行

函数创建
函数的作用域关系在函数创建时就已经执行

函数执行

-预编译/预处理
	-初始化作用域(链)
	-初始化this(箭头函数没有此操作)
	-初始化arguments(箭头函数没有此操作)
	-变量提升
		变量提升:声明(var)
		函数提升:整体
-执行代码

执行上下文:存放此次函数相关的一系列内容的一个对象
执行栈:存放执行上下文

当函数开始执行时,函数生成一个对应的私有执行上下文,放入执行栈中;当函数执行结束时,此执行上下文会被移出执行栈,并被销毁

执行栈(ECS)的空间有限,如果内容的执行栈数量超过其容纳限度,将会出现爆栈(错误)

执行上下文(EC:execute context)

-函数执行上下文EC(sum)
-全局执行上下文EC(G)

执行上下中组成(ES3)
-变量对象:用于存储当前函数定义的变量
-作用域(词法作用域):获取变量->词法环境
-this(最新的语法标准中,this位于变量环境)
this 指向问题:

  - 默认指向:window (严格模式:undefined)

  - 隐式指向:当函数有调用者时,执行调用函数的对象
  - 显示(强制)指向:
    - call,apply: 更改 this 指向,立即执行函数 (call,apply 的区别在于传递参数的方式不一样)
    - bind : 更改 this 指向, 返回一个绑定了指向的新函数
  - 箭头函数:自身没有 this, 从父级中获取 (无法修改)
  - 事件绑定:绑定事件的元素
  - new 绑定: 指向创建出来的对象

上下文规则总结
原型

二、闭包

定义

官方定义:
一个函数和对其周围状态(Lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包圈),这样的组合就是闭包(closure)

通俗定义:
当函数嵌套函数,其内部函数使用了外部函数的变量

产生原因

解决内部函数需要在需要使用外面函数的变量时,不能因为外部函数由于执行结束,执行上下文被销毁而无法供内部函数使用

闭包函数:内部函数
闭包对象:存储内部函数使用的外部函数的变量的对象

闭包缺点:
-耗内存:由于内部函数一直存在,所以对应的闭包对象会一直存在直到内部函数被回收
内存泄漏:部分内存长久被占用着,无法被释放掉(例如定时器,闭包未清除)

闭包优点:
-让局部变量生命周期更长
-可以让变量不易被其他内容修改

三、面向对象编程

1.对象

定义:key-value结构,用于存储属性和方法的数据集合
创建对象:
-原生
-构造函数 let obj = new Object()
-字面量/直接量:let obj ={}
-自定义构造函数

构造函数(类):
-本质就是一个普通函数,只不过调用方式和使用目的不同
-调用方式:使用new关键字
-使用目的:生成具有特定功能属性的对象
通过构造函数创建的对象称为实例对象

如果在不使用new关键字的情况下,调用构造函数,会发生什么?
-首先,返回值将不是一个对象,而是undefined
-而且会在window中生成原本应该属性对象中的属性,污染全局环境
-可以使用new.target判断是否用过new关键字进行调用,解决非new调用

补充:如果没有new一个对象,可以编写“抛出错误”
抛出错误
或者直接给它强制添加上new
强制添加上new

2.new关键字

1.生成一个空对象
2.将this指向生成的对象
3.当代码执行结束,如果函数没有返回对象,将返回this,如果返回了对象,则返回定义的该值

3.原型(原型对象)

->解决函数的重复创建
-在每个构造函数上,都存在一个属性prototype,其指向一个空对象,即原型对象,当前构造函数所创建的实例对象,都可以访问到这个原型对象
-将公共方法放置在原型对象,解决了方法的重复创建

原型链:

-当在实例对象访问一个属性方法时,如果自身没有,会在其对应的原型对象上去寻找;如果原型上也没有,由于原型对象也是由另一个构造函数(默认为Object)所创建,所以原型对象又能访问其自身对应的原型对象,依次向上查询,直到Object构造函数的原型对象上没有位置

原型对象

实例对象间互相访问:
-构造函数->原型:prototype
-原型->构造函数:constructor
-实例对象->原型:proto
-实例对象->构造函数:实例对象->原型->构造函数
-原型->实例对象:不能
-构造函数->实例对象:不能

对象方法

复制对象 Object.assign(target,…sources); ->浅拷贝
创建对象 Object.create(property) *
在这里插入图片描述

属性描述符(属性)–了解

● configurable:可配置性/删除
● enumerable:可枚举性/可遍历性
● value:属性值
● writable:可写性
在这里插入图片描述
在这里插入图片描述

● getter&setter:属性拦截器(只能拦截属性)
● proxy:对象代理(直接把整个对象的所有属性都可以监听到,拦截所有对象,性能也更高)

对象遍历

● for in 注意:会将原型上的属性和方法一并遍历出来
● Object.keys() 遍历属性名,返回数组,不包含不可枚举属性

● Object.values() 遍历属性值,返回数组,不包含不可枚举属性

● Object.entries() 遍历属性值,返回包含属性名和属性值的二维数组,不包含不可枚举属性

● Object.getOwnPropertyNames() 获取对象的所有属性名,包含不可枚举属性
● Object.getOwnPropertySymbols() 获取对象的所有symbols属性

原型控制
● Object.getPrototypeOf()
● Object.setPrototypeOf()

4.深浅拷贝

对象拷贝:通过遍历对象属性,将当前对象中的属性复制到新对象中
浅拷贝:在进行对象拷贝时,不区分数据是否是对象类型;如果拷贝对象内部嵌套对象,则拷贝后的对象和原有对象会出现关联,内部对象出现变量,拷贝对象和新对象同步更改
深拷贝:在进行对象拷贝时,区分数据类型,如果是对象类型,则需要单独进行拷贝一份,以保证拷贝对象和新对象毫无关联,相互独立
实现方式:
浅拷贝:
● Object.assign
● 扩展运算符
● 遍历
深拷贝
● JSON
JSON: javascript object nation -> 文本格式(字符串)
Object -> JSON: JSON.stringify()
JSON -> Object: JSON.parse()

JSON缺陷只能转换一些常用的属性,不能转换函数类型

● 遍历
○ 拷贝的数据类型,原来是什么类型,就应该生成对应的数据类型
○ 判断拷贝内容是否是对象,不是对象直接返回
○ 处理循环引用

编程范式:
面向过程编程
面向对象编程
函数式编程

5.面向对象编程

面向对象编程特性
● 封装
● 继承
● 多态
○ 重写
○ 重载
面向过程
优点:逻辑简单;性能好
缺点:可读性;可维护性;可复用性;可扩展性
面向对象
优点:可读性;可维护性;可复用性;可扩展性
缺点:逻辑比较复杂;性能开销大

对象封装
● 原始模式
● 工厂模式
● 构造函数
● 原型模式
● 组合模式:构造函数+原型
● class语法:组合模式的语法糖(限制非new的调用)
在这里插入图片描述

静态属性、方法
static开头命名
私有属性以#开头命名,只能在class语法中使用

6.对象继承

● 原型链继承:将子类的原型设置为父类的实例对象,扩展原型链
○ 缺点:会在子类的原型上添加无用的空属性(所以产生原型式继承)
在这里插入图片描述

○ 最好还是重新指正一下constructor

● 原型式继承
在这里插入图片描述

● 借用构造函数继承
● 组成继承:原型链+借用构造函数
● 寄生组合继承:原型式 + 借用构造函数
● class 继承

此处的super等效于,子类属性必须写在super之后
在这里插入图片描述

7.解构

(一般运用于参数很多的情况)
在这里插入图片描述

对象解构

数组解构,按照位置来解构
a.
b.arr1=3,4,5
实际情况运用
在这里插入图片描述

如果没有传参,可以用以下写法
在这里插入图片描述

总结

乱七八糟的,将就着看吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值