ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JavaScript高级笔记

2022-07-07 23:05:47  阅读:158  来源: 互联网

标签:__ 函数 对象 JavaScript 高级 笔记 作用域 原型 prototype


基础深入

undefined 和 null 的区别

undefined 是定义了一个变量但没有赋值
null 是定义了一个变量并赋值为null

数据的类型

基本类型 --> String Number Boolean undefined null
引用类型 --> Object function array

变量的类型

值类型 --> 保存的是基本数据类型(值)
引用类型 --> 保存的是引用数据类型(地址值)

typeof

两个特殊的:null 和 array
typeof null = 'object'
typeof array = 'object'

其余的数据类型 typeof 都是返回它本身
typeof undefined = 'undefined'
typeof function = 'function'

对象

多个数据的封装体
组成:
属性(字符串 属性值是任意值)
方法(属性值是函数)

数组:arr[索引值]
对象:obj['属性名'] -> [ ]内可以接收变量

属性名包含特殊字符的时候 使用 obj['属性名']

函数

什么是函数?
实现特定功能的 n 条语句的封装体
只有函数是可以执行的

为什么要用函数?
提高代码复用、便于阅读理解

定义函数

1.函数声明

function 函数名(形参){
  n 条语句
}

2.表达式

var fn = function(形参){
  n 条语句
}

执行函数
1.fn() -> 直接调用 (this:window)
2.obj.fn() -> 以方法形式调用 (this:obj)
3.new Fn() -> 通过new调用 (this:新创建的对象)
4.fn.call/apply(this) -> 指定函数 this 调用
如果不指定this则与直接调用没区别

call方法:
fn.call(指定函数fn的this,实参1,实参2,...)
apply方法:
fn.apply(指定函数fn的this,[实参1,实参2,...])

call指定实参是分开的
apply指定实参是用数组封装起来的

回调函数

call back

  • 我定义的
  • 我没有主动调用
  • 但最终调用了

立即执行函数

(function(形参){
  n 条语句
})()

将匿名函数用()括起来看作一个整体,然后末尾加上()表示调用

作用
()内的是匿名函数是局部作用域,不会污染外部(全局)命名空间

JS分号问题

可以不加分号(根据个人喜好)
但是又两个特殊的地方必须加
()前必须加
[]前必须加

var a = 3
;(function(){})() //立即执行函数

函数高级

原型 prototype

  • 每个函数对象都有一个prototype属性,它默认指向一个空Object对象(称为:原型对象)
  • 每个函数的原型对象都有一个constructor属性,它引用函数本身
  • 例:Person.prototype.constructor === Person
  • 函数创建的所有实例对象 都可以访问到原型对象中的属性或方法
  • 实例对象.constructor === 构造函数.prototype.constructor
  • [constructor出现在函数的原型对象prototype身上就是为了 让这个函数所创建的所有实例能 通过.constructor来获取构造函数]

显式原型、隐式原型

显式原型
每个函数都有一个 prototype 属性 即 显式原型

隐式原型
每个实例对象都有 一个 即 __ proto __ 隐式原型

原型对象其实也是一个实例对象 由 Object 创建的 所以也有__proto__这个属性
隐式原型对象 指向 缔造者(构造函数)的原型对象

关于原型的两个内部语句

function Fn(){
/*
  内部语句:this.prototype = new Object() 
  等同于:this.prototype = {}
  prototype对象中的 默认 添加constructor这个属性
*/
}

var fn = new Fn()
// 内部语句 this.\__ proto \__ = Fn.prototype

原型链

每个函数都有 显式原型对象 和 隐式原型对象
显式原型对象 .prototype 是由 Object函数创建的
隐式原型对象 .__proto__ 指向这个函数 的 缔造者的 原型对象 Function.prototype

查找变量
变量通过作用域找不到 报错
通过对象.属性 查找一个变量找不到 返回undefined
实例对象.属性 通过原型链找不到这个属性 返回 undefined

  • Object 是一个函数
  • Function是一个函数

1.函数的显式原型指向的对象默认是 Object的实例对象(但Object除外)
原型链终点:Object.prototype.__proto__ === null Object的原型对象
2.任何函数都是new Function() 创建的(包括Function本身)
所以 任何函数的__proto__都是Function.prototype

Function.__proto__ === Function.prototype // true

实例对象的 隐式原型对象 等于 构造函数的 显示原型对象

原型链是 .__proto__.__proto__.__proto__ 连起来的一条链子

instanceof

表达式 A instanceof B
返回一个布尔值
如果函数B的显示原型prototype 在 A实例对象的原型链上,则返回true

变量声明提升

var
var 声明变量,会在所有代码执行之前声明(但没赋值)
声明了没赋值 undefined

/*
var 没有块级作用域的概念,所有的var变量提前声都是在 作用域的顶部声明。
注意:只有函数才能切割全局作用域
所以 var声明 只有两个情况:
1.在全局作用域的顶部声明
2.在局部作用域的顶部声明


Tips: if 没有切割作用域(只有函数才能切割全局作用域)
*/

ES6中:let 和 const 才有块级作用域的概念

函数声明提升

function
function 函数名(){} 会在所有代码执行之前创建,所以可以在函数声明前调用函数
var 函数名 = function(){} 声明了,但没赋值,不能再声明前调用函数

  • 函数提升 比 变量提升的优先级高,函数、变量同名,不会被变量声明覆盖,但是会被变量赋值之后覆盖

执行上下文

全局执行上下文

1.所有代码执行之前 将 window 确定为全局执行上下文

2.对全局数据进行预处理

  • var 定义的变量 ==> 赋值 undefined ,添加为window的属性
  • function 声明的全局函数 ==> 赋值 ,添加为window的方法
  • this赋值为window

3.开始执行全局代码

函数执行上下文

1.准备调用函数之前,创建对应的函数执行上下文对象

2.对局部数据进行预处理

  • 形参变量 赋值 实参,添加为执行上下文的属性
  • arguments 赋值 实参列表(伪数组),添加到执行上下文的属性
  • var 定义的变量 ==> 赋值 undefined ,添加为window的属性
  • function 声明的全局函数 ==> 赋值 ,添加为window的方法
  • this 赋值为 调用函数的对象

3.开始执行

4.函数执行完毕释放空间,清除执行上下文

栈(stack)的结构

后进先出
window压栈

作用域链

  • 每个函数都会创建自己的作用域,作用域在函数定义时就已经确定了
  • 全局执行上下文是在全局作用域确定之后,JS 代码执行之前创建的
  • 关键:作用域是静态的,只要函数定义好了就一直是这样不会变化。
  • 执行上下文是动态的,调用函数时创建,函数执行完毕就会自动释放

闭包

如何产生?

当一个嵌套的内部函数引用了外部函数的变量时,就产生了闭包

闭包是什么?

理解一:闭包是嵌套的内部函数
理解二:在内部函数中 有一个 包含被引用变量的对象(closure)

我的详细理解

/*
父函数 里面嵌套 子函数
子函数 引用了 父函数的数据
父函数 将 子函数返回return,一个变量接收父函数的返回值
通过这个变量可以调用子函数,但是调用子函数 必须用到 父函数的数据
父函数 return 之后 代表已经执行完毕。
正常情况:一个函数执行完毕会释放内存空间,清除执行上下文。
关键是 子函数 还要用到 父函数的数据 所以 父函数 return之后 数据还存在于内存中
没有被清除,这就形成了闭包
*/

产生条件

  • 函数嵌套
  • 内部函数引用了外部函数的数据
  • Tips:不用调用内部函数就已经产生了闭包

闭包次数问题

外部函数被调用了几次就产生了几个闭包

常见的闭包

1.将内部函数作为返回值返回
2.内部函数作为实参传递给另一函数调用

闭包的作用

1.使函数内部的变量在函数执行完毕之后,仍然存活在内存中
2.让函数外部可以操作到函数内部的数据

闭包的生命周期

产生:内部嵌套的函数 定义执行完毕时就产生了
死亡:内部嵌套的函数 称为垃圾对象时(垃圾对象会被浏览器垃圾回收机制清除)

闭包的应用

定义JS模块

  • 将所有数据和功能都封装在一个函数内部(私有化)
  • 向外暴露一个包含 n 个方法的对象或函数
  • 模块的使用者,只需要通过模块暴露的对象调用方法来实现对应的功能

闭包的缺点

1.函数执行完毕之后,函数内的局部变量没有释放,占用内存
2.容易造成内存泄露
解决:能不用闭包就不用,及时释放(= null)

内存溢出、泄露

内存溢出
程序运行占用内存过大,导致溢出,会报错

内存泄露

  • 占用的内存没有及时释放
  • 泄露过多久会导致内存溢出
    常见的内存泄露:
    1.意外的全局变量
    2.没有及时清理定时器 或 回调函数
    3.闭包

对象高级

对象的创建模式

Object 构造函数

  • 先创建Object对象,再动态添加属性和方法
  • 适用场景:起始不确定对象的内部数据
  • 缺点:语句太多

对象字面量

  • 使用{}创建对象,同时添加属性和方法
  • 适用场景:创建前就知道对象的内部数据
  • 缺点:如果创建多个对象,有重复代码

工厂模式

  • 定义一个函数,这个函数每次return对象
  • 适用场景:需要创建多个对象
  • 缺点:对象没有确切的类型,多个对象区别不开

自定义构造函数

  • 自定义构造函数,通过 new 创建对象
  • 适用场景:需要创建多个类型确定的对象
  • 缺点:每个对象都有相同的数据(方法),浪费内存

构造函数与原型组合

  • 自定义构造函数,属性在 new 的时候初始化,方法添加到原型身上
  • 适用场景:需要创建多个类型确定的对象时

原型链继承

子类型的原型对象 为 父类型 的 实例对象
使 子类型的原型对象.__proto__ === 父类型.prototype
原本 子类型的原型对象.__proto__ === Object.prototype

子类型创建的实例对象 的 原型链上就可以找到 父类型的原型对象
可以调用夫类型原型对象身上的属性或方法

/*
A是父类型构造函数 实例对象 a
B是父类型构造函数 实例对象 b

b.__proto__ === B.protoype
B.prototype.__proto__ === Object.prototype

` <!-- 关键: 使子类型的原型对象 为 父类型的 实例对象 -->`
B.prototype = new A()
`<!-- 修正constructor属性,要不然就找到父类型的原型对象.constructor -->`
B.prototype.constructor = B 

`<!-- 这时 B.prototype 就是 A的 实例对象-->`
B.prototype.__proto__ === A.prototype

b 就可以通过原型链找到 A.prototype ,能找到就能使用 A 原型身上的属性或方法
但 b 是 new B() 创建的

这就让 B 继承了 A
*/

线程机制

这里没弄太明白

进程和线程

多进程:一个应用程序可以同时启动多个实例运行
多线程:在一个进程内,同时由多个线程运行

  • JS 是单线程运行的
  • 浏览器是多线程运行的

分线程

var worker = new Worker('worker.js')

  • 不会阻塞主线程

不常用原因:
1.慢
2.不能跨域加载JS
3.worker 内代码不能访问 DOM 更新页面,因为全局作用域看不到window和document
4.不是每个浏览器都兼容

标签:__,函数,对象,JavaScript,高级,笔记,作用域,原型,prototype
来源: https://www.cnblogs.com/imycc/p/16456501.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有