javascript基础


JavaScript ( JS )诞生于 1995年 ,是一种具有函数优先的轻量级, 解释型的编程语言。
编译型语言是指运行之前将所有内容编辑后才开始运行,解释型语言是指在执行过程中进行编译。

JavaScript 标准ECMA制定(ECMA-262),维护组织为TC-39:ECMAscript发展委员会

ECMAscript规定了JS编程语法和基础核心知识,是所有浏览器厂商共同遵守的一套JS语法工业标准。

JavaScript和ECMAscript:JavaScript是ECMAscript的实现,ECMAscript是JavaScript的标准。

JavaScript和Java没有关系。

ES6是JavaScript的一个版本(ES2015之后的版本统称为ES6

JavaScript工作原理

采用单线程模式的嵌入式脚本语言 (运行在浏览器,node环境)

初期,设计初衷为运行在浏览器端的脚本语言(操作dom)
采用单线程方式(同一时间只能做一件事),执行代码的线程只有一个,任务是需要排队的,如果某一个任务执行时间长,就会出现阻塞
假设为多线程,可能会出现多个线程同时操作同一个dom的问题。

为解决阻塞问题,可以采用异步方式,setTimeOut某一些功能需要等待多长时间后执行 ;Ajax 通常也为异步,数据回来的时间不一定

JavaScript执行机制

  1. 先执行执行栈中的同步任务;
  2. 异步任务(回调函数)放入任务队列中;
  3. 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,则被读取的异步任务结束等待状态,进入执行栈,开始执行。

由于主线程不断的重复获取任务,执行任务,再获取任务,再执行,所以这种机制被称为事件循环

同步模式,代码按顺序执行,函数在调用时才会执行,代码被压入执行栈,执行后销毁,将结果输出到控制台;同一时间只能做一件事情。
同步任务都在主线程上执行,形成一个执行栈。
异步模式,异步消息压入(web api/node api)内部环境,一定时间后(按实际顺序)执行,执行时压入消息队列中,事件循环时刻检查消息队列中是否有消息,检测到有消息时,按顺序将消息压入执行栈中,销毁打印。同一时间可以做多件事情(一件事情的执行时间较长时,可以先执行下一件事情)。
异步任务放在消息队列中。
JS的异步是通过回调函数实现的。
异步任务主要有以下三种类型:

  1. 普通事件:如click,resize等;

  2. 资源加载:如load,error等;

  3. 定时器:setTimeout,setInterval等。
    异步不会影响同步执行。

     console.log(1);
    setTimeout(function(){
        console.log(3);
    },2000);
    console.log(2); // 1 2 3
    

    console.log(1);
    setTimeout(function(){
    console.log(3);
    },0);
    console.log(2); //1 2 3 先执行同步任务,再执行异步任务

浏览器执行js
浏览器分为两部分:渲染引擎和JS引擎,JS引擎也称为JS解释器,用来读取网页中的JavaScript代码,对其处理后进行运行。
浏览器本身并不会执行JS代码,是通过内置的JS引擎执行JS代码,JS引擎执行代码时逐行解释每一句源码,将其转换为机器语言,由计算机去执行。

js垃圾回收机制

主要解决内存泄露问题,内存泄露的含义是某些不需要的变量还存在内存
内存泄露:内存中存在一些不再需要的变量(垃圾,占用内存)
垃圾回收机制:间隔的不定期的寻找不再使用的变量,并释放。
两种方式:标记清除,引用计数
被视为垃圾的情况: 没有被引用的变量,几个对象相互引用形成闭环。
不会被视为垃圾的情况:全局变量(时刻待命),有具体的引用关系(证明有用,闭包)。
在函数功能体中,每一次执行完毕后,不被引用的变量会被销毁。

 function test(){
  //在函数的功能体中,每次执行完毕后,不被引用的变量会被回收
 	var num=0;
 	console.log(++num);
 }
 test();  //1
 test();  //1
 test();  //1

JavaScript的组成

ECMAScript(JavaScript语法)
DOM(页面文档对象模型,js操作html的api),通过DOM提供的接口可以对页面上的各种元素进行操作。
BOM浏览器对象模型,js操作浏览器的api),独立于内容,开发人员可以使用BOM控制浏览器显示的页面以外的部分,操作浏览器窗口

JavaScript的特点

  • 具有两面性
    可以在浏览器端运行: 使网页更丰富;进行表单验证(使用正则表达式);发送ajax请求;操作cookie;处理数据;dom/bom 操作;
    也可以在nodejs(服务器端)运行:后端开发;提供项目接口.

  • 解释性语言
    被内置于浏览器或者NodeJS平台中的JS解析器解析执行,执行前无需编译。

  • 弱类型语言 声明变量时,不需要指定他的数据类型,而变量的数据类型取决于赋值时值的数据类型(var a;), 且变量的数据类型可以随时发生改变

  • 从上往下顺序解析执行。

当把JavaScript引入代码放在头部时,因为代码是逐行进行的,所以body内的代码获取不到元素,需要放在body的底部

<head>
	<script src="./js/index.js" > </script>
</head>
<body>
	<div id="a1"> </div>              //null 不可获取a1
</body>
var a1 = document.getElementById (' a1 ');
console.log( a1 )

body>
	<div id="a1"> </div>
	<script src="./js/index.js" > </script>        //将js文件引入代码放在body底部,可以获取a1
</body>
var a1 = document.getElementById (' a1 ');
console.log( a1 )

给JavaScript引入代码中添加async或defer时,异步执行,js和body同时进行,可以获取到元素。

当页面引入多个js代码时,defer是两个js文件都加载完成后再开始按顺序先后执行,而async是先加载完成先执行后加载完成的后完成(注重顺序问题时使用defer,不注重顺序时使用 async

	<head>
	<script src="./js/index.js"  async> </script>   //添加async或defer,可以获取到a1
     </head>
	<body>
	<div id="a1"> </div>              
	</body>
	var a1 = document.getElementById (' a1 ');
	console.log( a1 )

window.οnlοad=function(){ } 其中的代码会等HTML页面所有代码加载完毕后再执行,就不必担心顺序问题

    <head>
	<script src="./js/index.js"  async> </script>   //添加async或defer,可以获取到a1
     </head>
	<body>
	<div id="a1"> </div>              
	</body>
	
	window.onload=function(){
	var a1 = document.getElementById (' a1 ');
	console.log( a1 )
	}

当在< script >标签中使用src=“ ” 引入js代码时,页面中< script >中再出现js代码时,会被忽略

	<head>
	<script type="text/javascript" src="hello.js"></script>
	<script  type="text/javascript">
	var str="hello world";
	console.log(str);
	</script>        // 忽略
	</head>

书写位置

  1. 行内式JS
    可以将单行少量JS代码写在HTML标签的事件属性中(以on开头的属性)

    < input type="button" value="点我" onclick="alert('Hello world')"/>
    
  2. 内嵌式

     < script >
     JS代码
     </ script>
    
  3. 外部引入

     < script src="js地址"> < / script>
    

运行环境

1.浏览器运行

  • 在HTML文件中在script标签中写js代码或在html页面中引入外部js代码,再用浏览器运行;
  • 在浏览器控制台可以直接编写js代码;

2.电脑上运行:(需要安装node环境)

  • cmd打开电脑终端,node回车编写代码,node index.js 或 node index 运行js代码
  • vscode 中在英文状态下按Ctrl+~打开集成终端,进行js代码编写和运行
    在vscode中安装插件:
    npm i nodemon -g (全局安装)可以自动检测文件的更改,重新启动程序,方便调试;
    nodemon index.js 使用插件运行文件,修改保存文件后,自动重启,ctrl+c结束进程
    插件安装npm i readLine-sync
    使用:const readLine = require(‘readLine-sync’)
    var input = readLine.question(‘请输入×××’);

3.云服务器运行:(node环境下)

Linux系统
cmd ssh连接云服务器;
安装node;
node -v 检测node版本;
touch 创建文件;
vi index.js 使用vi编辑器编辑文件,若文件不存在则创建新文件进行编辑;
node index.js执行js代码;
cat index.js 查看文件内容;
node 回车进行编辑js代码;
node编辑状态下的命令:
.clear清空实例,
.editor进入编辑模式可以同时输入多行代码,ctrl+d键会将代码结果进行打印。
ctrl+c退出编辑help帮助,
.exit退出node环境
.load加载已存在的文件,
.save将刚编辑的代码进行保存,
.save 文件名 : 将已经写好的代码保存到文件中

注释

单行注释:// (ctrl+ / )
多行注释: /* */ (shift+Alt+ a)

输入输出语句

alert(msg) 浏览器弹出警示框,展示给用户
console.log(msg) 浏览器控制台打印输出信息,展示给开发人员
prompt(info) 浏览器弹出输入框,用户输入。

关键字和保留字

关键字:(在JS中有特殊功能)
保留字:(将来可能成为关键字)

js是区分大小写的(HTML是不区分大小写的,css严格区分大小写):typeof 关键字, typeOf 非关键字

标识符

指变量,函数,属性的名字或者函数的参数。

标识符是按照以下规则组合起来的一或多个字符(严格区分大小写):

  1. 字母,数字,下划线,$ 组成;
  2. 只能以字母,下划线,$开头;
  3. 不能将关键字或保留字作为标识符(尽量不要使用name作为变量名);
  4. 命名采用驼峰式命名:
    大驼峰式(类名):UserName;
    小驼峰式(变量名,函数):userName;
  5. 名称尽量有意义(不能使用中文)

语句

每个语句以分号结尾,如果省略分号,由解析器确定语句的结尾,即分号可以省略,但是我们要求每个语句的末尾都应该有分号。

变量

变量是一个存放数据的容器,该容器的值可以随时改变。可以通过变量名访问内存中分配的空间。

本质:变量是程序在内存中申请的一块用来存放数据的空间

ECMAScript的变量是弱类型(松散类型),可以用来保存任何类型的数据。

定义变量时使用var关键字。

变量只能声明一次,重复声明无效。声明在内存中申请一个空的空间。

变量可以重复赋值

node中运行js时,变量保存在global中;在浏览器中运行时,变量保存在window

变量的使用:

声明 var message;
赋值 message = “hello”
初始化(声明并赋值) var message = “hello”;
定义多个变量 var message= “hello”, found=false, age = 29; var a =b=c= 3;
变量调用 console.log(message);

变量名的命名规则:

  1. 变量名由字母,数字,下划线以及$组成。
  2. 不要使用下划线或者数字作为变量名的开头
  3. 变量名应该具有一定的意义,使用小驼峰命名规则 var userAgeTotal = “”;
  4. 不要使用关键字或是保留字

变量的声明

声明变量的本质是去内存申请空间
var用于声明一个变量,在es6中,可以通过let声明一个变量,通过const声明一个常量

	var a =b=c= 3;
	var d=10,e=20,f,g;

特殊情况:

  1. 只声明,不赋值 : undefined

     var age;
     console.log(age);
    
  2. 不声明,不赋值,直接使用 : 报错

     console.log(age); 
    
  3. 不声明,只赋值 : 不会报错但是不建议这样使用

     age=10;
     console.log(age);
    

变量提升

全局块中的变量声明会自动提升到全局代码块的最顶端,但是赋值不会被提升;
同理局部快中的声明会被提升到局部代码的最顶端,赋值不会被提升。

1)  console.log(a);  // 变量未声明就打印会出错 error 

2)  var a;
        console.log(a);  //undefined

3) console.log(a);
	  var a;    //  undefined  不会报错,在代码执行前全局块中的声明会自动提升到全局代码块的最顶端
	  等价于
	  var a;
	  console.log(a);

4)  var a=0;
	  function test() {                                     var a;
		console.log(a);        等价于                console.log(a);
		var a=1;										  a = 1;
	 }
	test ();  	//undefined  局部代码块中声明(var=a)会被提升到局部代码块的最顶端,但赋值(a=1)不会提升
	console.log(a);    //a=0

5) var a=0;
	  function test() {
		console.log(a);
		var a=1;
		console.log(a)
	  }
	  test ();  	//undefined   a=1     局部代码块中声明(var=a)会被提升,但赋值(a=1)不会提升
	  console.log(a);    //a=0

如果在函数中定义变量没有加var,该变量为全局变量

	function test(){
	message = "hello";       //message为全局变量
	}
	test();
	alert(message);     //可以访问

用var操作符定义的变量将成为定义该变量的作用域中的局部变量

	var a = 1;      //局部变量
	function b() {
	a = 10;    //全局变量
	return;
	}
	b();
	console.log(a);  //10

全局变量不能获取局部变量,而局部变量可以获取到全局变量

1)function test(){
		console.log(a);
		var a=1;  //局部变量
	}
	console.log(a);    ///error  全局中不能获取局部变量中的值

2)x = 1;  //全局变量
	console.log(x); //1
	function y() {
      console.log(x);   //undefined
      console.log(this.x);  //1
      var x = 2;   //局部变量
      console.log(x); //2
      }
      y();
      console.log(x); //1

3)var a = 1;        //a函数声明,提前变量a,将a认为是函数b作用域的变量,具有局部效果
	function b() {
	a = 10;      //全局变量
	return;
	function a(){}
	}
	b(); 
	console.log(a); 

4)function test() {
		a=3;
		console.log (a)
	}
	console.log(a);  //不能获取到a的值,因为此时函数还未执行
	test();  
	console.log(a);  //函数执行后可以获取到a的值

变量的作用域

全局变量和局部变量。javascript的作用域是相对函数而言的,可以称为函数作用域
全局作用域: 最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的;
局部作用域: 局部作用域一般只在固定的代码片段内可访问到,而对于函数外部是无法访问的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值