资讯专栏INFORMATION COLUMN

JS预解释

daydream / 3051人阅读

摘要:预解释基础知识先介绍的基本数据类型基本数据类型值操作有引用数据类型引用地址执行环境当浏览器加载页面的时候,首先会提供一个供全局代码执行的环境全局作用域如下代码是在中好好学习天天向上把整个函数定义的部分函数本身在控制台输出

预解释 1. JS基础知识 1.1 先介绍js的基本数据类型

基本数据类型 --- 值操作

有number、string、boolean、null、undefined

引用数据类型 ---- 引用地址

object、array、Date

1.2 执行环境

当浏览器加载HTML页面的时候,首先会提供一个供全局JS代码执行的环境 --- 全局作用域(global/window)

如下代码是在script中

var num = 12;
var obj = { name:"houdashuaige", age:18 };
function fn() {
    console.log("好好学习 天天向上");
}
console.log(fn) //把整个函数定义的部分(函数本身)在控制台输出
console.log(fn()) //输出当前函数的执行返回结果
fn()//return 后面是啥 返回啥 如果没有return 返回undefined

示意图如下

如果执行obj.age = 20;
首先通过地址xxxfff000 找到对应的空间 然后把空间中age属性对应的属性值修改为20;
其中fn存储的是一个地址 代表的时当前函数的整体
2. 预解释 2.1 预解释的基本概念
在当前的作用域中,JS代码执行之前,浏览器首先会默认地把所有带var、function的进行提前的声明或者定义
2.1.1 理解声明(declare)和定义(defined)
var num = 12;
声明: var num; //告诉浏览器在全局作用域中有一个num的变量

定义: num = 12(发生在代码执行过程中 不在预解释中);  //给变量进行赋值

function fn() {
    console.log("this is a test");
}
函数预解释
fn = xxxfff000; 
声明: fn //告诉浏览器在全局作用域中有一个fn的函数
定义: fn = xxxfff000; //给fn赋值 指向函数的地址

注释: 所以对于带var 和 function关键字的在预解释的时候操作还是不一样的

**var: 对于带var的变量 预解释只会声明 不会进行定义**
**function: 在预解释的时候声明+定义 一起完成了**

附代码

//函数只有在执行的时候才会对函数内部的代码进行预解释
console.log(num);// undefined 提前声明 但未定义 默认undefined
var num = 12;
console.log(num);// 12
var obj = { name: "hou", age: 7 };

fn(100,200);//代码可以在这执行 因为预解释的时候 声明+名义就已经完成了

function fn(num1,num2) {
    var total = num1 + num2;
    console.log(total);
}

附示意图

2.1.2 函数预解释(代码内部)
function fn(num1,num2) {
    var total = num1 + num2;
    console.log(total);
}

附示意图

2.1.3 JS中内存的分类(预解释发生在栈内存)
//栈内存:用来提供一个供JS代码执行的环境 --->作用域(全局作用域/私有作用域)
//堆内存:用来存储引用数据类型的值 --->对象存储的时属性名和属性值
//函数存储的是代码字符串
2.1.4 如何区分私有变量和全局变量(主要用来分析函数预解释)

注释: 下述都是为了更好地理解"函数预解释",请耐心阅读

"全局作用域"下声明(预解释的时候)的变量是全局变量

"私有作用域"中声明的变量和"函数的形参"都是私有的变量

在私有作用域中,我们代码执行的时候遇到了一个变量,首先我们要确认它是否是私有的变量,
如果是私有的变量,那么和外面的变量没有任何的关系,如果不是私有的,则往当前作用域的
上级作用域查找,如果上级作用域没有则继续查找,一直找到window为止 --->("作用域链")

当函数执行的时候(直接目的:让函数体中的代码执行),首先会形成一个新的私有作用域,然后按照如下步骤执行:
a:如果有形参,先给形参赋值
b:进行私有作用域中的预解释
c:私有作用域中的代码从上到下执行

函数形成一个新的私有作用域保护了里面的私有变量不受外界的影响(外面修改不了私有的,私有的也修改不了外面的)形成了"闭包" --->(保护机制)

2.1.5 全局作用域中,带var和不带var的区别

区别1: 带var的可以进行预解释,所以在赋值的前面执行不会报错,不带var的是不能进行预解释的,在前面执行会报错

代码如下

console.log(num);--->undefined
var num = 12;
console.log(num2); --->直接报错 因为num2没有预解释
num2=13;

区别2: 看下述代码

var num = 12;
console.log(num);//12
num2 = 12;
console.log(num2) //12 --->相当于window.num2
//关系:num2 = 12 --->相当于给window增加了一个叫num2的属性名,属性值是12
//var num =12 --->相当于给全局作用域增加了一个全局变量num,但是不仅如此,
//它也相当于给window增加了一个属性名num,属性值是12

函数内部不带var的代码如下

var total = 0;
function fn() {
    console.log(total) // 0
    total = 100;//相当于修改了全局变量total
}
fn();
console.log(total)//--->100
//注释:私有作用域中出现的一个变量不是私有的,则往上级作用域查找,上级没有则继续向上查找,一直找到window
//如果window下没有 分两种情况:
//1、如果是获取值:console.log(total) -->直接报错
//2、如果是设置值:total = 100;--->相当于给window加了total属性
//3、JS中如果在不进行任何特殊处理的情况下,上边的代码报错,下边的代码都不执行了
2.1.6 预解释是一种毫无节操的机制

预解释的时候不管你的条件是否成立,都要把带var的进行提前声明

具体代码如下

if(!("num" in window)) { //===>if(false)
    var num = 12;
}
console.log(num);//--->实际输出undefined
//分析:不管if的条件是否成立 都会把带var的进行预解释 (var num = 12)
//所以"num" in window 是true  !("num" in window) --->false 
//if条件是false  var num = 12 不会执行 所以 console.log(num) 是undefined

匿名函数之函数表达式

把函数定义的部分当作一个值赋给我们的变量/或者赋给元素的某一个事件

fn();//====>fn 是undefined 相当于 undefined()  报错 uncaught TypeError: fn is not a function
//window下的预解释 var fn; 预解释的时候只会预解释 "="(等号)左边的
//右边的是值  不参与预解释
var fn = function() {
    console.log("ok");
}

自执行函数

定义和执行一起完成的

//自执行函数定义的那个function在全局作用域下不进行预解释,当代码执行到这个位置的时候,定义和执行一起完成了
//自执行函数的5种形式
(function(num){})(100);//常用形式
~function(){}(100);
+function(){}(100);
-function(){}(100);
!function(){}(100)

函数内部return相关

function fn() {
    console.log(num);//--->undefined
    return function() {};
    var num = 100;
}
fn();
//函数体种return 下面的代码虽然不再执行了,但是需要进行预解释
//return 后边跟着的是我们的返回值,所以不进行预解释

预解释经典习题解析

//注释:在预解释的时候,如果名字已经声明过了,不需要重新声明,但是需要重新定义(赋值)
//JS比较懒,声明过一次,便不再声明,但是可以重新定义
//在JS中,如果变量的名字和函数的名字重复了,也算冲突
fn();
function fn() {console.log(1)};
fn();
var fn = 10;
fn();
function fn() {console.log(2)};
fn();
//输出结果是2 、2 、 报错:fn is not a function 后边代码不执行

附解释图

(自己画预解释图 学习 分析会更快 更有效)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100249.html

相关文章

  • 关于js解释

    摘要:之前经常会听到预解释,预解释,那么预解释到底是什么今天就来浅谈一下下。所以预解释是只发生在当前作用域下的,只有函数执行的时候函数中的才会预解释。而是在预解释的时候,既要声明又要定义,所以是有值的。 之前经常会听到预解释,预解释,那么预解释到底是什么?今天就来浅谈一下下。预解释也是我们平时说的变量提声,在当前作用域中js代码执行之前,浏览器首先会默认的把所有的带var和function的...

    yankeys 评论0 收藏0
  • JavaScript-编译

    摘要:预编译发生在函数执行前也就是说函数执行时,预编译已经结束。五总结理解预编译需要明白变量函数声明和变量赋值。预编译阶段,只进行变量函数声明,不会进行变量的初始化即变量赋值,所有变量的值都是变量赋值是在解释执行阶段才进行的。 一、JS的概念 JavaScript ( JS ) 是一种具有函数优先的轻量级解释型或即时编译型的编程语言。 二、JS语言特点 2.1 单线程 (1)JavaScri...

    Aldous 评论0 收藏0
  • JS 进阶 (一)作用域深入和面向对象

    摘要:进阶第一章作用域深入和面向对象预解释全局作用域当浏览器加载页面的时候,提供了一个全局代码执行的环境预解释变量提升在当前的作用域中,代码执行之前,浏览器首先会默认的吧所有带有和的进行提前声明或定义理解声明和定义声明告诉浏览器在全局作用域中有 JS进阶 第一章作用域深入和面向对象 预解释 1、全局作用域:当浏览器加载HTML页面的时候,提供了一个全局js代码执行的环境 2、预解释(变量提升...

    chengtao1633 评论0 收藏0
  • JavaScript的编译过程分析

    摘要:一概念是一个单线程解释型的编程语言。预编译大致可分为步创建对象找形参和变量声明,将形参和变量名作为属性名,值为将实参值和形参统一在函数体里面找函数声明,值赋予函数体。 一、JavaScript概念 JavaScript ( JS ) 是一个单线程、解释型的编程语言。 二、JavaScript语言特点 2.1 单线程 JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能...

    graf 评论0 收藏0
  • 5分钟读懂JavaScript编译流程

    摘要:大家都知道是解释型语言,既然是解释型语言,就是编译一行,执行一行,那又何来预编译一说呢脚本执行引擎都做了什么呢今天我们就来看看吧。全局域就是一切声明的全局变量,全是的属性等同于函数预编译发生在函数执行前一刻。 大家都知道JavaScript是解释型语言,既然是解释型语言,就是编译一行,执行一行,那又何来预编译一说呢?脚本执行js引擎都做了什么呢?今天我们就来看看吧。 1-JavaScr...

    Baoyuan 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<