声明提升
JS独有的奇葩设计: 代码运行的顺序 和 书写的顺序 可能不一致
JS引擎会在代码运行前, 找到所有的声明操作(var/function), 提升到作用域的顶部, 然后再执行调整顺序后的代码
差异
var: 只提升声明, 没有赋值. 其声明的变量 默认值undefined
function: 提升 声明+赋值
关于提升顺序: 公认的说法是 函数比 var 提升更靠前
正常书写代码的要求:先声明 再使用
面试题: 面试官用一堆 不常用的, 错误的写法 来考你
宿主环境
JS运行时, 所在的环境-- 常见node.js + 浏览器
浏览器提供的window对象
携带了大量的 操作浏览器相关的 方法/属性
称呼: 全局对象 / 全局作用域
全局对象中的方法, 可以直接调用, 省略 window 前缀
作用域: 一类具有特殊功能的 对象类型 的称呼
全局: window对象, 放系统提供的API
全局污染: 把自定义的属性存储在window里, 就称为污染
局部: 函数作用域, 函数运行时临时生成的对象, 存放了函数中声明的变量
销毁: 函数运行完毕, 会自动销毁 -- 例外 : 闭包
作用域链: 多层作用域嵌套的场景, 使用一个变量时, 按照就近原则 从上层作用域找最近的用
闭包
1个函数, 使用了其他函数作用域中的变量
怕: 其他函数作用域自动销毁, 导致变量消失
解决: 把其他函数作用域存放在自己的 scopes 属性里
闭包: 这个被存储在scopes属性中的 函数作用域, 称为闭包
用途: 制作私有的变量, 给函数使用, 不污染全局
范式:
var 函数 = (function(){
var 变量 = 值..
return function(){}
})() 函数: arguments
函数自带的变量, 存储了 所有收到的实参
用途1: 制作实参数量不固定的函数 -- 比如 max 求最大值
用途2: 多功能函数的制作 -- 函数重载
根据参数的 个数 或 类型 不同, 通过判断执行不同的代码逻辑
函数: this
概念: this代表函数运行时所在的对象 -- 是谁在用函数
简单粗暴看格式:
对象.方法名(): 方法的this就是 对象
方法名(): 方法的this是window
对象: 引用类型
对象是个可变化大小的类型:可以存放任意多个属性, 存储在堆内存
变量中保存的是 对象的内存地址. 引用了对象的内存地址
浅拷贝: 创建一个新的对象, 把原对象的属性和值 挨个复制到新对象里
深拷贝: 看扩展视频--推荐面试前看 背下来即可
复习了对象的属性访问方式
点语法: 对象.属性名
方括号: 对象[JS代码]
var a = 'mike' 对象[a] -> 对象['mike'] 对象.a 就是读a
1.认识构造函数
可以理解为 为电脑装系统,哪台电脑要装系统, 就去找 U盘/光盘 来安装即可。


构造函数通常用 new 运算符触发, 用于生成对象,‘ -- ’ 用来构造对象的函数, 称为构造函数
使用new的创建构造函数的语法是 var emps = new Array('lili', 'mike', 'lucy', 'john')
JS为对象提供了语法糖的方式进行创建,书写为 var emps = ['lili', 'mike', 'lucy', 'john']

2.构造函数的实现
构造函数是用于构造对象 的函数,有自己的命名规范:用大驼峰写法(带大写的)给构造函数命名,其目的是为了让使用者见名知意。
生成一个矩形对象,每传入一对值 ,就会生成一个长和宽的对象

3.构造函数+方法
制作一个矩形对象: 拥有长、宽两个属性, 额外能计算面积和周长

tips:
原型是一个共享的存储区域, 专门存放对象共享的方法
__proto__: 称为原型链,即用于链接到原型的属性
prototype: 作者为构造函数提前准备了共享方法存储的区域,prototype用于存放共享方法

此处r1.area运行的流程是,r1 会先查找自身是否有 area 名称的属性,如果没有,就会到共享方法区域 __proto__ 存储的地址中找有没有。
注意:这里的 r1 的 area 和 r2的area 是同一个(console.log(r1.area == r2.area) //true) r1.area 是 构造函数的prototype.area,r2.area 是 构造函数的prototype.area, 所以他们是同一个。
这样放在外部书写函数设计的优势在于,生成一次, 然后共享使用 ,节省内存资源, 每个对象都使用公共的方法,如果放在构造函数里写: 每次调用都生成一个新的函数, 浪费内存。
类似于,一个父亲的三个孩子共享父亲的住房,原有构造函数的写法需要一个孩子一套房。
作者提供new运算符协助构造函数的使用,通过new运算符触发的函数, 将会自动完成3行代码
1. 制作空对象, 赋值给关键词this
2. 对象的原型链 指向 构造函数的原型
3. 返回对象
面试题一,console.log(s1)的结果

答案:{sname:"楠楠"}
解析: 理论上: 构造函数不需要写return, 因为new运算符会自动返回,但是一旦手写了return, 则默认的返回操作会失效,优先采用 显式声明的return。
面试题二,console的结果

解析: 这里考察的是两种用法的this区别,new 函数(): var this = {}, 函数() : window。
(更多面试题参考教师笔记)
ES5: JS的第五个版本 -- 2009年,发布的了严格模式特性:JS属于“早产儿”: 为了快捷开发, 所以采用了 弱类型特征,另外很多报错不完善, 代码本身有很多风险;2009年出品了: 严格模式, 需要手动开启. JS引擎会提供更多的报错服务, 把错误隐患暴露出来, 辅助程序员写出更加 健壮的代码;推荐: 大家以后写代码都要手动开启严格模式, 各大web默认页都开启严格模式。
'use strict' //在JS开头书写此行, 就开启严格模式,严格模式下: 变量必须先声明 再使用。
如果没有使用严格模式,可能会有以下风险。
1.变量名写错污染全局

2.严格模式下, 直接调用函数, 其中的this 是undefined,有效防止意外的全局变量声明 -- 构造函数忘记写new。
如果面试官问: 说一说 严格模式下 有哪些更改?
严格模式下: 取消了静默失败,有了报错之后, 更容易定位BUG。
1.将属性配置为不可更改

2.精确配置 emp 的 salary 属性, 让其无法被遍历

3.让salary 不可遍历, 让 eid 不可修改

4. 为对象新增属性
注意:使用此语法新增的属性, 所有配置项都是假 不可写 不可遍历 不可配置

