Object.prototype
console.dir(Object)
Array.prototype
console.dir(Array)
dir -> 查看一个对象的详细信息
API怎么使用 -> MDN -> 看到该API的语法,以及作用
为什么要整理它们的方法?
因为现在我们用Vue和React都是用数据渲染视图,这意味着我们需要操作数据,而最常见的数据、最难操作的数据,无外乎就是数组和对象
所以你必须得把常用操作数据的API都给弄熟了,唯有弄熟了,你才能对服务器传过来的数据,然后想出各种方案去处理它们……不然,你不熟的话,你真的不知道该如何处理这些数据……
如何才算弄熟呢?
一提到数组,你就想到它的CRUD数组元素的方法、遍历迭代数组元素的一些方法、类方法
对基础知识非常熟 -> 才会有项目经验、编程经验 -> 如果你不熟,你很难想到xxx问题的解决方案,即便想到也要想个半天,你看半天过去了,你的代码一行都还没敲,这哪会有什么经验呀,更别提什么项目经验了 -> 人家3天一个项目,你写个半个月、1个月……
非常熟 -> 潜意识里看到这个东西就知道用什么API去处理这个数据…… -> 只有把基础知识搞扎实了,才能去搞一些逼格高的项目
非常熟 -> 确实,这一点我是没有想过的,我一直以为理解了就算了,但其实这还不够呀 -> 如果你对基础知识不熟,那么你是很难有思路去解决一些问题的……而且这会浪费很多时间……时间浪费了,技术成长就会非常慢……
我终于明白为啥之前有个同学背了大量的API,当时的我嗤之以鼻,认为用到了再去查就好了,其实当时我没有意识到「用到了」这三字,如果你不熟悉API的作用,那么你怎样确定你该去查哪个API呢? -> 总之,你要背熟API的作用,至于语法什么的,用到了再去查就好了!
可以把一些面试题作为引子,来引出接下来要讲的内容
如这样:
/*百度面试题*/
let a = 12;
let b = a;
b = 13;
console.log(a);
let a = {n:12};
let b = a;
b['n'] = 13;
console.log(a.n);
let a = {n:12};
let b = a;
b = {n:13};
console.log(a.n);
/*阿里面试题*/
let a = {
n: 10
};
let b = a;
b.m = b = {
n: 20
};
console.log(a);
console.log(b);
/*360面试题*/
let x = [12, 23];
function fn(y) {
y[0] = 100;
y = [100];
y[1] = 200;
console.log(y);
}
fn(x);
console.log(x);
白鹭引擎是基于V8引擎的二次开发,即 Egret Engine 是一款使用 TypeScript 编写的 HTML5 游戏引擎,包含渲染、声音、用户交互、资源管理等诸多功能
简单来说,我们写的JS代码 -> 词法解析+语法解析+构建AST抽象语法树(想想Schema,我们写的代码,即字符串,需要把其解码成AST) -> 运行时 -> 基本类型+内部类型
简单解释编译器的处理过程:
如:
var a = 12;
xxx拿到这个,按照一定规则,把无用的,有用的,给拎出来,注意有些字符在某种环境下是有用的,而另一种环境下则是无用的……
把有用的拎出来后,就语法解析,构成一个AST树 -> 抽离结构,让浏览器的V8引擎可以识别然后执行
整个系列课程接下来主要讲的是:
JS运行时这部分内容,即引擎这部分内容
JS运行时搞懂了(知其然) -> 编译器(AST) -> C/C++ -> 汇编语言(创造语言) -> 编译器(AST) -> JS运行时(再看JS运行时,知其然知其所以然)
从高级CV -> 到搞点能给人CV的东西……
浏览器拿到一个可执行的代码结构,有了结构,那么接下来就需要有一个可以执行代码的环境——ECStack
ECStack:Execution Context Stack 执行环境栈 -> 栈内存
栈内存 -> 内存就是一个地儿的意思 -> 栈内存 -> 目的:提供了一个供代码执行的环境
EC:Execution Context 执行环境(执行上下文) -> 注意,这可不是作用域哈!
EC涉及到两个概念:
你把这俩概念具象化成类似盒子之类的东西(都装有代码),同样,你把ECStack也具象化成一个类似盒子之类的东西(提供一个环境用来执行代码的)
浏览器需要把创建的上下文(盒子)压缩到ECStack这个大盒子里边去执行 -> 进栈
执行完:
如果你在面试的时候,有人问到了底层机制,那么你要说出这些专业术语
GO:全局对象(Global Object)
注意,这是在浏览器的GO,而不是Node.js 里边的
浏览器天生自动init一个GO,然后赋值给了window,即window = {xxx:xxxx……}
当然,有了这些内置的对象还不够,还要有自定义的,如 var a = 12;
,那么这个 a
就在跑到window旗下了
一般现在都是用let、const了,因为用let、const声明的全局变量不会污染window对象
题外话:
关于变量赋值这个操作:
变量赋值分三步走:
所以 var a = 12;
的读法是:
声明了一个变量
a
,并定义它的状态为12
-> 这俩操作都会开辟内存
关于常量?
let a = 12;
let b = a;
b = 13;
console.log(a);
变量只能指向一个值,这是一夫一妻制
关于基本值,你写了一个常量出来,就会在栈开个内存出来存这个值,如你让
b = 12;
那么,就会多个12的值,而不是都是指向那个a所指向的12
为什么叫引用类型?
let a = {n:12};
let b = a;
b['n'] = 13;
console.log(a.n);
在上边的代码里边:
a
a存储的是引用值,所以这a是「引用类型」的变量
创建出来的堆能销毁吗?
我们释放一个堆内存,可以这样:
a = 0
// or
a = null
不过前者会明显会占用栈内存,而且也不符合情理,即你给了它一个0值,但又用它。因此我们不会选择它,而是选择后者 null
(告诉后来看代码的人该变量已GG),而这是 null
的第一个作用
null
的第二个作用,需要拿 undefined
来比较
我们仅仅只声明一个变量,那么表示 这个变量有没有值是不确定的,而如果你在声明变量的时候,给它赋了一个 null
值,那么这表示之后我们会给这个变量一个值,只是目前我们不确定该给它什么值比较好
说白了:
在其它语言里边可没有
undefined
,只有null
-> 表示空对象指针
连等操作的意思
a = b= 13
表示:
对于带 eval 的动态语言来说,变量名是储存的,比如 JS 的每个 Environment Record 就存了所有的局部变量,以及访问链。
Environment Record -> ECMAScript Specification Types -> 只存在于规范里的抽象类型
而
对于 C/C++ 这种编译成机器代码的语言:
变量名不需要储存,所有的局部变量读写都会变成(栈地址 + 偏移)的形式。
允许子程序嵌套的语言比如 Pascal/ML,读写非局部变量会经由访问链(Access link)去读其他的栈帧,但是变量名也会变成一个索引(整数),不会在内存中出现的。
也就是说在JS里边,变量名是占用内存空间的咯!
➹:变量名储存在哪里,变量的储存机制是什么? - Belleve的回答 - 知乎
只要0x开头,至少有3个数值起步就好了,如0x101
一般都是写7位的,如 0xe60e02f
:
➹:内存地址是12位16进制数,那么对应的指针需要多少字节? - 知乎
➹:内存地址空间为何用十六进制表示(pamp分析基础)_c/c++_一叶舟的专栏-CSDN博客
所以设置一个值为 null
是合理的,如 objA.valueA = null;
但设置一个值为 undefined
是不合理的
话说null占内存吗?
应该会占用内存,可我们用null并不主要是因为内存的原因:
➹:undefined与null的区别 - 阮一峰的网络日志
➹:JavaScript 中 null 和 undefined 的区别? - 知乎