预解析、对象、错误

文章详细阐述了JavaScript中的单线程特性,解释了浏览器为何是多进程但JS是单线程的。同时,介绍了预解析机制,包括函数和变量的提升,以及函数和变量同名时的处理规则。此外,文章还讨论了作用域的概念,包括全局和局部作用域,以及如何避免隐式全局变量。最后,提到了对象的创建、new关键字的使用以及this的指向问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.单线程

(1)线程和进程

        进程是 cpu 资源分配的最小单位(是能拥有资源和独立运行的最小单位)

        线程是 cpu 调度的最小单位(线程是建立在进程的基础上的一次程序运行单位,一个进程中可以有多个线程)

        单线程与多线程,都是指在一个进程内的单和多。(所以核心还是得属于一个进程才行)

(2)浏览器是多进程 ,JavaScript是单线程的

        总结一句话:如果没有遇到条件或者循环,程序按照顺序从上往下依次执行

(3)定时器 

          window.setTimeout(code,millisec);//等待一段时间(millisec)后执行一次函数内容,只执行一次

           window.setInterval(code,millisec);//每隔一段时间(millisec)执行一次函数内容

           window.可以省略 

        清除定时器

          clearTimeout(定时器的ID)

          clearInterval(定时器的ID)

(4)同步异步 

        同步任务(从上到下,依次执行)

        异步任务(暂时挂起,先运行排在后面的任务)

       异步编程主要有:1、setTimeout  2、ajax回调函数  3、promise对象   4、generator函数         5、事件机制

2.预解析(将以关键字var和function开头的语句块提前进行处理

        当变量和函数的声明处在作用域比较靠后的位置的时候,变量和函数的声明会被提升到作用域的开头赋值不会被提升。        

(1)函数提升表达式声明的函数不会被提升

func();

function func(){

alert("Funciton has been called");

}

        由于JavaScript的预解析机制,上面的代码就等效于:

function func(){

alert("Funciton has been called");

}

func()

(2)变量提升 

alert(a);

var a = 1;

        上面的代码就等效于

var a;  //这里是声明

alert(a); //变量声明之后并未有初始化和赋值操作,所以这里是 undefined

a = 1

(3)函数同名,后覆盖前

func1();

function func1(){

console.log('This is func1');

}

func1();

function func1(){

console.log('This is last func1');

}

输出结果为

This is last func1

This is last func1

原因分析:由于预解析机制,func1的声明会被提升,提升之后的代码为

function func1(){

console.log('This is last func1');

}

func1();

func1();

用function声明的函数:同名的函数,后面的会覆盖前面的

函数表达式声明的函数:不会覆盖,采用就近原则。

(4)变量和函数同名(变量会被忽略,或变量覆盖函数——看顺序)

alert(foo);

function foo(){}

var foo = 2;

        当出现变量声明和函数同名的时候,只会对函数声明进行提升,变量会被忽略。所以上面的代码的输出结果为

function foo(){}

预解析之后的代码:

function foo(){};

alert(foo);

foo = 2;

第二种:

var num = 1;

function num () {

alert( num );

}

num();

代码执行结果为:

Uncaught TypeError: num is not a function

按照常规的书写顺序,同名的函数与变量,变量会覆盖函数

预解析后的代码:

function num(){

alert(num);

}

var num = 1;

num();

(5)预解析是分作用域的(局部可以用全局变量,全局不能用局部变量) 

3.作用域

(1)全局作用域

        在全局作用域中有一个全局对象 window(代表的是一个浏览器的窗口,由浏览器创建),可以直接使用。

        所有创建的变量都会作为 window 对象的属性保存

(2)局部作用域(函数作用域)

        在函数内部就是局部作用域,这个代码的名字只在函数的内部起作用

        调用函数时创建函数作用域,函数执行完毕之后,函数作用域销毁

        每调用一次函数就会创建一个新的函数作用域,它们之间是相互独立的。

(3)隐式全局变量

        声明变量使用`var`, 如果不使用`var`声明的变量就是全局变量( 禁用 )

(4)作用域及作用域链 

        全局作用域---全局变量

         局部作用域---局部变量---只在当前作用域下有效

         块作用域?(ES5中没有,ES6中存在)

只有函数才能产生局部作用域

        作用域链的查找规则:

            先从当前的作用域中查找,如果有,就返回

            如果没有从上一级查找,有就返回,没有继续上一级查找,直到全局

            如果全局没有,就报错

4.对象 

(1)对象的创建方式

         1.对象字面量

                var obj1 = { name: "zs", sex: "男", age: 20 }

        2.内置构造函数new Object()创建对象

                var person = new Object();
                  person.name = 'lisi';
                  person.age = 35;

        3.工厂函数创建对象

        function createPerson(name, age, job) {
          var person = new Object();  //创建对象
          person.name = name;
          person.age = age;
          person.job = job;
          person.sayHi = function(){    //函数,对象行为
            console.log('Hello,everyBody');
          }
          return person;    //返回对象
        }
        var p1 = createPerson('张三', 22, 'actor');

        4.自定义构造函数(要求名称首字母大写(规范))

        function Person(name,age,job){
          this.name = name;
          this.age = age;
          this.job = job;
          this.sayHi = function(){       //行为,创建函数
            console.log('Hello,everyBody');
          }
        }
        var p1 = new Person('张三', 22, 'actor');

(2)new关键字——用来在创建对象时初始化对象

         1.构造函数用于创建一类对象,首字母要大写

  2.构造函数要和new一起使用才有意义

new在执行时会做三件事情:

                1.new会在内存中创建一个新的空对象

        var person = new Object();  //创建对象

        2.new会让this指向这个新的对象

        3.new会返回这个新对象

 (3)this详解

函数内部的this几个特点:

        1. 函数在定义的时候this是不确定的,只有在调用的时候才可以确定

        2. 一般函数直接执行,内部this指向全局window

        3. 函数作为一个对象的方法,被该对象所调用,那么this指向的是该对象

        4. 构造函数中的this其实是一个隐式对象,类似一个初始化的模型,所有方法和属性都挂载到了这个隐式对象身上,后续通过new关键字来调用,从而实现实例化

(4)对象的使用 

       1. 取出对象属性对应的属性值有两种方法

        方法一:obj.name——(对象.属性)

        方法二:用[ ](数组的方式)

obj1[name]——(对象[属性])

2.遍历对象的属性

通过for..in语法可以遍历一个对象

对象的key(属性名)不会重复,如果有,后面会覆盖前面

 

   也可以 for(value in obj1){  } 

      3.利用对象key(属性名)不重复的特性进行数组去重

        过程:1.遍历数组,把数组的每一项当作对象的属性名

                  2.取出所有的属性名,加入到新数组

数组为字符串类型

 数组为数字类型

        将arr2.push(key)——>arr2.push(Number(key))

     4.删除对象的属性(delete 

        delete obj.name; 

5.JavaScript错误(了解)

(1)JavaScript  try(尝试运行) 和 catch(捕获异常)

        try 和 catch 是成对出现

         var txt="";

         function message() {

         try { adddlert("Welcome guest!"); }

        catch(err) { txt="本页有一个错误。\n\n";

          txt+="错误描述:" + err.message + "\n\n";

         txt+="点击确定继续。\n\n";

         alert(txt);

        } }

(2) finally语句

        finally 语句不论之前的 try 和 catch 中是否产生异常都会执行该代码块

         finally { document.getElementById("demo").value = ""; } }

(3)throw语句——创建或抛出异常

语法:throw exception

 function myFunction() { var message, x; message = document.getElementById("message"); message.innerHTML = ""; x = document.getElementById("demo").value; try { if(x == "") throw "值为空"; if(isNaN(x)) throw "不是数字"; x = Number(x); if(x < 5) throw "太小"; if(x > 10) throw "太大"; } catch(err) { message.innerHTML = "错误: " + err; } }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值