一. JavaScript简介
1.历史
JavaScript(简称JS)是一门弱类型(变量可以被隐式转换为另一个类型)、结构化、动态化、基于原型的面向对象的解释性脚本语言。(script就是脚本的意思)
1995年,网景公司一位名叫Brendan Eich的工程师,开始为即将发布的Netscape Navigator 2开发一个叫Mocha(后来改名叫LiveScript)的脚本语言。当时的计划是在客户端和服务器端都使用它,它的服务器端叫Live Wire。
为了赶上发布时间,网景与sun公司结为开发联盟,共同完成LiveScript的开发。就在Netscape Navigator 2正式发布之前,网景把LiveScript改名为JavaScript,以便搭上媒体当时热烈炒作Java的顺风车,日后这成为大众对这门语言有诸多误解的原因之一。
发布很成功,尚未成熟的Web的受欢迎程度受到了历史新高,这时,微软决定向IE投入更多资源。就在Netscape Navigator 3发布不久,微软发布了IE3,其中包含了自己名为JScript的JavaScript实现。这意味着出现了两个版本的JavaScript:Netscape Navigator的JavaScript 和 IE的JScript。
为了统一标准,1997年,TC39委员会花了数月打造出ECMA-262,也就是ECMAScript(发音为“ek-ma-script”)这个新脚本语言标准。1998年,国际标准化组织(ISO)和国际电工委员会(IEC)也将ECMAScipt采纳为标准。自此以后,各家浏览器均已ECMAScript作为自己JavaScript实现的依据。
2.组成
完整的JavaScript实现包含以下几个部分:
- 核心(ECMAScript)
- 文档对象模型(DOM)
- 浏览器对象建立模型(BOM)
JavaScript ECMAScript DOM BOM
2.1.ECMACcript
是对实现ECMA-262规范描述的所有方面的一门语言的称呼,描述包括了脚本语言的语法、类型、语句、关键字、保留字、操作符、全局对象。拓展接口(如DOM)使用ECMAScript核心类型和语法来添加原来环境没有的功能。
2.2.DOM
是一个应用编程接口(API),将整个页面抽象为一组分层节点,HTML、XML页面的每个组成部分都是一种节点,包含不同的数据。通过DOM接口的这个特性,我们可以对页面上的各种元素进行操作(删除、添加、替换、修改节点,大小、位置、颜色等)。
2.3.BOM
提供了与浏览器交互的方法和接口(API),提供了独立于内容的、可以与浏览器窗口进行互动的对象结构,用于支持和操作浏览器的窗口,主要针对于浏览器的窗口和子窗口,比如弹出窗、移动缩放和关闭浏览器窗口。
3.浏览器执行JavaScript
浏览器内部分为两部分:
①渲染引擎:用来解析HTML与CSS,俗称内核,比如 chrome 浏览器的 blink ,老版本的 webkit
②JS 引擎:也称为 JS 解释器。 用来读取网页中的JavaScript代码,对其处理后运行,比如 chrome 浏览器的 V8
二. 怎样使用JavaScript
1. 引用的三种方法
1.1.行内式的js,直接写在元素内部
<input type="button" value="坐忘道" onclick="alert('娃,你着相了!')">
1.2.内嵌式的js,写在<head>底部,用<script>属性
1.3.外部式的js,用<script>属性
2.添加注释
单行注释:// 多行注释:/**/
vscode中在设置中进行更改默认快捷方式来自定义注释的快捷键
3.输入输出语句
长按F12可以查看控制台看到如下画面:
4.三种脚本属性
4.1.推迟执行脚本:defer
告诉浏览器应该立刻下载该脚本,但是执行应该延迟,即浏览器解析到结束的</html>标签后才才执行。
defer属性只对外部脚本文件有效。
4.2.异步执行脚本:async
同样是只适用于外部脚本,告诉浏览器立刻开始下载,但标记为async的脚本并不能像defer一样按照他们出现的次序执行。
告诉浏览器,不必等到脚本下载和执行完后再加载页面,同样也不必等到该脚本下载和执行后再加载其他脚本。
4.3.动态加载脚本
通过DOM API,向DOM中动态添加script元素同样可以加载指定脚本,只要创建一个script元素并将其添加到DOM中即可。
5.针对不支持JavaScript的浏览器该怎么使用JavaScript
使用 <noscript>元素,它可以包含任何可以出现在<body>中的HTML元素。
以下任何一个条件满足,包含在<noscript>中的内容就会被渲染,否则,<noscript>中任何内容都不会被渲染:
- 浏览器不支持脚本
- 浏览器对脚本的支持被关闭
三. 基本语法
1.变量
1.1.命名
1.由字母(A-Za-z)、数字(0-9)、下划线(_)、美元符号( $ )组成
2.严格区分大小写。test 和 Test 是两个变量
3.第一个字符必须是字母、下划线(_)、或美元符号( $ )
4.不能是关键字、保留字。比如:const、var、eum、package、let又如:typeof是关键字,不能用作变量名,但是Typeof可以
5.推荐使用驼峰命名法:首字母小写,后面单词的首字母需要大写,比如:myCar
1.2.声明
1.2.1 var
var 是一个 JavaScript的关键字,用来声明变量( variable的汉译是变量)。使用该关键字声明变量后,计算机会自动为变量分配内存空间,不需要考虑变量的类型。
- 我们可以一次声明一个或多个变量
var message = 'hi', a = 235 , popo = 2698.5456;
- 我们可以在声明的时候省略 var ,这是合法的,但是此时的该变量将自动升级为全局变量,让我们来看样例:
- 除此之外还需要注意声明的提升:
不会报错,那是因为ECMAScript运行时把它看作成等价于如下代码:
1.2.2 let
let 作用与 var 作用差不多,但是有着重要的区别:let 的声明范围是块区域,而var 的声明范围是函数作用域,举个例子:
- 不允许在块区域内重复声明,否则会报错:SyntaxError
let age;
let age;
- 不会在作用域中被提升,会报错:ReferenceError ;没有定义
console.log(age);
let age = 20; //不会被提升
1.2.3 const
作用域基本与 let 相同,唯一的区别就是被他声明的变量的值不可被改变,还有就是声明的同时一定要初始化,即要给他赋值。
1.3 原数值和引用值
ESMAScript变量包含两种不同的数据:原始值和引用值。
原始值:最简单的数据
引用值:由多个值构成的对象,保存在内存中,因为JavaScript不允许直接访问内存,所以 我们操作的不是对象所在的内存空间,而是操作对该对象的引用
- 确定类型,要用 typeof 关键字(对原始值很有用),对判断引用值他是一个什么类型的对象就不怎么起作用了,这是我们要用 instanceof :
let a = 22;
console.log(typeof a); // number
console.log(person instanceof Object);//变量 person 是 Object 类型吗?是返回true,不是返回false
关于类型的知识我们放在后面讲。
2.数据类型
JavaScript 把数据类型分为两类:
简单数据类型 (Undefined,Number,String,Boolean,Symbol(ECMAScript6新 增),Null)
复杂数据类型 (object)
2.1 Undefined
Undefined类型只有一个值,就是特殊值undefined,当使用 var 或 let 声明了变量却没有初始化时,就相当于给变量自动赋予了 undefined 值。
2.2 Null
同样只有一个特殊值 null ,是一个假值,表示一个空指针:
let car = null;
console.log(typeof car); // "Object"
null 和 undefined 在定义上表面相等:
2.3 Boolean
布尔类型有两个字面量:true 和 false。true不等于1,false不等于0.
- 要将其他类型的值转化为布尔类型,可以调用Boolean()转型函数
- 在 if()等控制语句中,会自动执行其他类型到布尔类型的转化
2.4 Number
表示所有整数和浮点数。
- 表示整数时,可以表示不同进制的数
八进制:第一个数字必须是0
十六进制:数值前缀必须式0x
2. 浮点数:数值中必须有小数点,小数点后面必须有一个数字,若小数点后面没有整数或整数为0,会被当作整数
3. NaN:意思是“不是数值”,像0/0,-0/+0返回的都是NaN,还有一点(NaN==NaN)返回的是false。isNaN() 是一个非数字,用来判断一个变量是否为非数字的类型,返回 true 或者 false。
2.5 String
字符串型可以是引号中的任意文本,其语法为双引号 " "和单引号’ ’,JavaScript可以用单引号嵌套双引号,也可以用双引号嵌套单引号,例如:
var 二狗 = 'hhhhhhh,成了,成了!哈哈哈,"他"就要来了';
如果想打出换行、横线这些转义字符,我们需要用到字符串转义符
字符串长度通过.length来获取。
剩下的东西有点多,但是基本已经学完了,写的时间有点不够了,打算把剩下的部分在下周培训之前补上,大约还剩下数据类型的转换,特别是String类型中要用到的方法以及和Number的转换,各个进制之间的运算,操作符以及结构语句,函数的三种声明,函数的默认参数及其扩展,函数声明与函数表达式的区分,函数内部的:arguments,this,caller,new.target;函数属性和方法,异常编程中的同步与异步、期约、异步函数,还有对数组的介绍:Object、Array、ArrayBuffer、Map、WeekMap、Set、WeakSet等,还有对对象的相关理解。
关于学长留的问题,我有个思考:
输出是0、1、2,因为只有前三个定时器的回调函数被执行并打印它们的参数i值到控制台。第四个定时器的回调函数未执行,因为它的定时器被取消了。
改进:
function fn1() {
for (var i = 0; i < 4; i++) {
var tc = setTimeout(function (i) {
console.log(i);
}, 10, i)
//i为回传参数
clearTimeout(tc);
}
}
fn1();