欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JavaScript高级

程序员文章站 2022-05-08 15:54:32
...

一、原型

prototype属性

  1. 函数都有一个prototype属性,默认是一个Object空对象
  2. 函数对象中都有一个constructor,它指向函数对象
  3. 给函数原型对象添加方法,其实例对象可以调用

fun.prototype.constructor === fun //true

JavaScript高级
ps:

空对象:没有自身的属性

    function fun(params) {
        
    }
    console.log(fun.prototype)

JavaScript高级

二、函数高级

a.原型与原型链

原型上的方法是给其实例对象使用的
每个函数function上都有一个prototype,即显示原型属性
每个函数function上都有一个__proto__,即隐示原型属性
对象的隐式原型的属性值是其构造函数的显性原型的值

    function Fun(){     // 内部:this.prototype = {}
    }
    var fn = new Fun()   //内部  this.__protp__ =  Fn.prototype
    console.log()
    console.log(Fun.prototype === fn.__proto__)   // true   地址值   都是指向原型对象

JavaScript高级

函数prototype是函数定义时自动添加的,默认空对象;对象__proto__是创建对象的时候自动添加的,默认指向构造函数的prototype属性值

原型链

JavaScript高级
JavaScript高级

Person构造函数和fun都未曾定义过toString,为什么不像fun.test()一样报错呢?

JavaScript高级
JavaScript高级

1.函数的显示原型指向的对象默认是空Object实例对象(但Object不满足)
Person.prototype instanceof Object //true
Object.prototype instanceof Object //false
2.所有函数都是Function的实例对象(包括Function)
3.Obect的原型对象是原型链的尽头(null)

    function An() {
        
    }
    An.prototype.a = 'test'
    var an1 = new An();
    an1.a = 'test1'
    var an2 = new An();
    console.log(an1.a,an2.a)  // test1  test

读取对象的属性值,会先在自身上找,再通过原型链找
设置对象的属性值,不会查找原型链,如果当前对象没有属性,会直接追加,再设置值

JavaScript高级

b.执行上下文与执行上下文栈

.执行上下文
1.全局执行上下文

  • 全局将window为执行上下文
  • 对全局数据进行处理
    • 声明提前,变量注意 var let const ,函数注意 var n = fun(){} 与 function xx()
    • 变量与函数同名,var 声明并复制,权重最大
    • this 指向 window
  • 执行
    2.函数执行上下文
  • 在调用函数,准备执行函数前,创建对应的函数执行上下文
  • 对局部数据进行预处理
    • 形参变量,赋值(实参),添加为执行上下文的属性
    • argument(类数组),赋值(实参列表),添加为执行上下文的属性
    • var 定义的局部变量,为undefined,添加为执行上下文的属性
    • function声明的函数,赋值,添加执行上下文的方法
    • this 赋值(调用函数的对象)
  • 开始执行函数体
    执行上下文栈

在全局代码执行前,JS引擎就会创建一个栈来存储管理所有的执行上下文对象;
在全局执行上下文(window)确定后,将其添加到栈中(压栈)
在函数执行上下文创建后,将其添加到栈中(压栈)
在当前函数执行完后,将栈顶的对象移除(出栈)
在所有的代码执行完,栈中只有window
ps:
栈:后进先出
队列:先进先出

JavaScript高级

c.作用域(scope)与作用域链

全局作用域
函数作用域在函数定义的时候就确定了,而不是说调用的时候
局部作用域
块级作用域
注意var 变量的位置
作用域是静态的,而上下文是动态的,比如函数调用或结束时改变

作用域是由内向外,依此查找,注意声明的地方

d.闭包

闭包:嵌套的内部函数,包含这被引用变量(函数)的对象。闭包存在于嵌套的内部函数。
看变量a与变量b区别,a内部调用,就产生闭包,b就不产生
JavaScript高级
闭包产生:
1.函数嵌套
2.内部函数调用局部调用
3.内部函数定义执行完
闭包的作用
1,使用函数内部的变量在函数执行完,仍然存活在内存中,延长局部变量的生命周期
2.让函数外部可以操作(读写)到函数内部的数据
闭包的缺点
优点有时候也是缺点,清除赋值null
a.内存溢出
b.内存泄漏

三、线程机制与事件机制

线程

  • 进程:进程是指程序的一次执行,它占有一片独有的内存空间,
  • 线程:线程是指CPU的基本调度单位,是程序执行的一个完整流程,是进程内的一个独立执行单元。多线程是指在一个进程内, 同时有多个线程运行。

js 单线程

  • JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊。

  • JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假如JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?

  • 所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变。

  • 为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。

  • 这里所谓的单线程指的是主线程是单线程的,所以在 Node 中主线程依旧是单线程的。

  • 因为是单线程,所以所有任务都需要排队,前一个任务结束,后一个任务才能执行,如果前一个任务花费时间较长,后一个任务等待时间也随之变长。

  • js可以做到先把等待中的任务先放一边晾着,去处理后面的任务

  • 于是所有任务可以分为两种,一种是同步任务,另一种是异步任务:同步任务很简单,前面的任务完成后面才能执行,一个接一个地执行任务。异步任务不占用主线程,直接进入“任务队列”中,等任务队列通知主线程,某个任务可以执行了,才会进入主线程执行。

异步执行机制

  • 所有同步任务都在主线程上执行,形成一个执行栈。
  • 主线程之外,还存在一个“任务队列”。只要异步任务有了运行结果,就在“任务队列”中放置一个事件。
  • 一旦执行栈中的所有同步任务都执行完毕,就会去“任务队列”中读取新的任务放到执行栈中,再依次执行任务。
  • 只要主线程空了,就会读取任务队列,这就是js的运行机制。这个过程会不断地重复。
相关标签: js javascript