特别注意:Undefined 不是 Null
在 JavaScript 中, null 用于对象, undefined 用于变量,属性和方法。
对象只有被定义才有可能为 null,否则为 undefined。
如果我们想测试对象是否存在,在对象还没定义时将会抛出一个错误。
错误的使用方式:
if (myObj !== null && typeof myObj !== "undefined")
正确的方式是我们需要先使用 typeof 来检测对象是否已定义:
if (typeof myObj !== "undefined" && myObj !== null)
程序块作用域
在每个代码块中 JavaScript 不会创建一个新的作用域,一般各个代码块的作用域都是全局的。即:在一个代码块中,所有的语句共用一个作用域
以下代码的变量 i 返回 10,而不是 undefined:
实例
for (var i = 0; i < 10; i++) {
// some code
}
return i;
JavaScript中的分号
虽然在 JavaScript 中,分号是可选的 。
但是要注意 return 的用法:
这样的语句是完整的:
return
执行时 JavaScript 将自动关闭语句:
return;
由于 return 是一个完整的语句,所以 JavaScript 将关闭 return 语句。
所以不用对 return 语句进行断行。
JavaScript 表单
JavaScript 表单验证
HTML 表单验证可以通过 JavaScript 来完成。
以下实例代码用于判断表单字段(fname)值是否存在, 如果不存在,就弹出信息,阻止表单提交:
JavaScript 实例
function validateForm() {
var x = document.forms["myForm"]["fname"].value;
if (x == null || x == "") { alert("需要输入名字。"); return false; } }
以上 JavaScript 代码可以通过 HTML 代码来调用:
HTML 表单实例
<form name="myForm" action="demo_form.php" onsubmit="return validateForm()" method="post">
名字: <input type="text" name="fname">
<input type="submit" value="提交">
</form>
数据验证
数据验证用于确保用户输入的数据是有效的。
典型的数据验证有:
- 必需字段是否有输入?
- 用户是否输入了合法的数据?
- 在数字字段是否输入了文本?
大多数情况下,数据验证用于确保用户正确输入数据。
数据验证可以使用不同方法来定义,并通过多种方式来调用。
服务端数据验证是在数据提交到服务器上后再验证。
客户端数据验证 side validation是在数据发送到服务器前,在浏览器上完成验证。
HTML 约束验证
HTML5 新增了 HTML 表单的验证方式:约束验证(constraint validation)。
约束验证是表单被提交时浏览器用来实现验证的一种算法。
HTML 约束验证基于:
- HTML 输入属性
- CSS 伪类选择器
- DOM 属性和方法
约束验证 HTML 输入属性
属性 |
描述 |
disabled |
规定输入的元素不可用 |
max |
规定输入元素的最大值 |
min |
规定输入元素的最小值 |
pattern |
规定输入元素值的模式 |
required |
规定输入元素字段是必需的 |
type |
规定输入元素的类型 |
完整列表,请查看 HTML 输入属性。
约束验证 CSS 伪类选择器
选择器 |
描述 |
:disabled |
选取属性为 "disabled" 属性的 input 元素 |
:invalid |
选取无效的 input 元素 |
:optional |
选择没有"required"属性的 input 元素 |
:required |
选择有"required"属性的 input 元素 |
:valid |
选取有效值的 input 元素 |
JavaScript 表单验证
JavaScript 表单验证
JavaScript 可用来在数据被送往服务器前对 HTML 表单中的这些输入数据进行验证。
表单数据经常需要使用 JavaScript 来验证其正确性:
- 验证表单数据是否为空?
- 验证输入是否是一个正确的email地址?
- 验证日期是否输入正确?
- 验证表单输入内容是否为数字型?
E-mail 验证
下面的函数检查输入的数据是否符合电子邮件地址的基本语法。
意思就是说,输入的数据必须包含 @ 符号和点号(.)。同时,@ 不可以是邮件地址的首字符,并且 @ 之后需有至少一个点号:
function validateForm(){
var x=document.forms["myForm"]["email"].value;
var atpos=x.indexOf("@");
var dotpos=x.lastIndexOf(".");
if (atpos<1 || dotpos<atpos+2 || dotpos+2>=x.length){
alert("不是一个有效的 e-mail 地址");
return false; }
}
下面是连同 HTML 表单的完整代码:
实例
<form name="myForm" action="demo-form.php" onsubmit="return validateForm();" method="post">
Email: <input type="text" name="email"> <input type="submit" value="提交"> </form>
JavaScript 验证 API
约束验证 DOM 方法
Property |
Description |
checkValidity() |
如果 input 元素中的数据是合法的返回 true,否则返回 false。 |
setCustomValidity() |
设置 input 元素的 validationMessage 属性,用于自定义错误提示信息的方法。 使用 setCustomValidity 设置了自定义提示后,validity.customError 就会变成true,则 checkValidity 总是会返回false。如果要重新判断需要取消自定义提示,方式如下:
|
以下实例如果输入信息不合法,则返回错误信息:
checkValidity() 方法实例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<p>输入数字并点击验证按钮:</p>
<input id="id1" type="number" min="100" max="300" required>
<button οnclick="myFunction()">验证</button>
<p>如果输入的数字小于 100 或大于300,会提示错误信息。</p>
<p id="demo"></p>
<script>
function myFunction() {
var inpObj = document.getElementById("id1");
if (inpObj.checkValidity() == false) {
document.getElementById("demo").innerHTML = inpObj.validationMessage;
} else {
document.getElementById("demo").innerHTML = "输入正确";
}
}
</script>
</body>
</html>
约束验证 DOM 属性
属性 |
描述 |
validity |
布尔属性值,返回 input 输入值是否合法 |
validationMessage |
浏览器错误提示信息 |
willValidate |
指定 input 是否需要验证 |
Validity 属性
input 元素的 validity 属性包含一系列关于 validity 数据属性:
属性 |
描述 |
customError |
设置为 true, 如果设置了自定义的 validity 信息。 |
patternMismatch |
设置为 true, 如果元素的值不匹配它的模式属性。 |
rangeOverflow |
设置为 true, 如果元素的值大于设置的最大值。 |
rangeUnderflow |
设置为 true, 如果元素的值小于它的最小值。 |
stepMismatch |
设置为 true, 如果元素的值不是按照规定的 step 属性设置。 |
tooLong |
设置为 true, 如果元素的值超过了 maxLength 属性设置的长度。 |
typeMismatch |
设置为 true, 如果元素的值不是预期相匹配的类型。 |
valueMissing |
设置为 true,如果元素 (required 属性) 没有值。 |
valid |
设置为 true,如果元素的值是合法的。 |
setCustomValidity 的用法:
var inpObj = document.getElementById("id1");
inpObj.setCustomValidity(''); // 取消自定义提示的方式
if (inpObj.checkValidity() == false) {
if(inpObj.value==""){
inpObj.setCustomValidity("不能为空!");
}else if(inpObj.value<100 || inpObj.value>300){
inpObj.setCustomValidity("请重新输入数值(100~300之间)!");
}
document.getElementById("demo").innerHTML = inpObj.validationMessage;
} else {
document.getElementById("demo").innerHTML = "输入正确";
}
JS保留关键字:
HTML 事件句柄
除此之外,您还应该避免使用 HTML 事件句柄的名称作为 Javascript 的变量及函数名。
实例:
onblur |
onclick |
onerror |
onfocus |
onkeydown |
onkeypress |
onkeyup |
onmouseover |
onload |
onmouseup |
onmousedown |
onsubmit |
非标准 JavaScript
除了保留关键字,在 JavaScript 实现中也有一些非标准的关键字。
一个实例是 const 关键字,用于定义变量。 一些 JavaScript 引擎把 const 当作 var 的同义词。另一些引擎则把 const 当作只读变量的定义。
Const 是 JavaScript 的扩展。JavaScript 引擎支持它用在 Firefox 和 Chrome 中。但是它并不是 JavaScript 标准 ES3 或 ES5 的组成部分。建议:不要使用它。
JavaScript 标准
所有的现代浏览器完全支持 ECMAScript 3(ES3,JavaScript 的第三版,从 1999 年开始)。
ECMAScript 4(ES4)未通过。
ECMAScript 5(ES5,2009 年发布),是 JavaScript 最新的官方版本。
随着时间的推移,我们开始看到,所有的现代浏览器已经完全支持 ES5。
JavaScript this 关键字
面向对象语言中 this 表示当前对象的一个引用。
但在 JavaScript 中 this 不是固定不变的,它会随着执行环境的改变而改变。
- 在方法中,this 表示该方法所属的对象。
- 如果单独使用,this 表示全局对象。
- 在函数中,this 表示全局对象。
- 在函数中,在严格模式下,this 是未定义的(undefined)。
- 在事件中,this 表示接收事件的元素。
this 的多种指向:
- 1、在对象方法中, this 指向调用它所在方法的对象。
- 2、单独使用 this,它指向全局(Global)对象。
在浏览器中,window 就是该全局对象为 [object Window]:
- 3、函数使用中,this 指向函数的所属者。
- 4、严格模式下函数是没有绑定到 this 上,这时候 this 是 undefined。
- 5、在 HTML 事件句柄中,this 指向了接收事件的 HTML 元素。
- 6、apply 和 call 允许切换函数执行的上下文环境(context),即 this 绑定的对象,可以将 this 引用到任何对象。
- call() 和 apply() 方法可以将 this 引用到任何对象。
显式函数绑定
在 JavaScript 中函数也是对象,对象则有方法,apply 和 call 就是函数对象的方法。这两个方法异常强大,他们允许切换函数执行的上下文环境(context),即 this 绑定的对象。
在下面实例中,当我们使用 person2 作为参数来调用 person1.fullName 方法时, this 将指向 person2, 即便它是 person1 的方法:
实例
var person1 = {
fullName: function() {
return this.firstName + " " + this.lastName;
} }
var person2 = { firstName:"John", lastName: "Doe" }
person1.fullName.call(person2); // 返回 "John Doe"
JavaScript let 和 const
ECMAScript 2015(ECMAScript 6)
ES2015(ES6) 新增加了两个重要的 JavaScript 关键字: let 和 const。
let 声明的变量只在 let 命令所在的代码块内有效。
const 声明一个只读的常量,一旦声明,常量的值就不能改变。
在 ES6 之前,JavaScript 只有两种作用域: 全局变量 与 函数内的局部变量。
注意点:全局变量在 JavaScript 程序的任何地方都可以访问。函数内使用 var 声明的变量只能在函数内容访问,但是如果不使用 var定义则是全局变量。
重新定义变量
使用 var 关键字重新声明变量可能会带来问题。
在块中重新声明变量也会重新声明块外的变量:
注:let 关键字就可以解决这个问题,因为它只在 let 命令所在的代码块 {} 内有效。
浏览器支持
Internet Explorer 11 及更早版本的浏览器不支持 let 关键字。
下表列出了各个浏览器支持 let 关键字的最低版本号。
谷歌 |
IE |
火狐 |
Safari |
|
Chrome 49 |
IE / Edge 12 |
Firefox 44 |
Safari 11 |
Opera 36 |
Mar, 2016 |
Jul, 2015 |
Jan, 2015 |
Sep, 2017 |
Mar, 2016 |
HTML 代码中使用全局变量
在 JavaScript 中, 全局作用域是针对 JavaScript 环境。
在 HTML 中, 全局作用域是针对 window 对象。
使用 var 关键字声明的全局作用域变量属于 window 对象:
在相同的作用域或块级作用域中,不能使用 let 关键字来重置 var 关键字声明的变量:
var x = 2; // 合法
let x = 3; // 不合法
{
var x = 4; // 合法
let x = 5 // 不合法
}
在相同的作用域或块级作用域中,不能使用 let 关键字来重置 let 关键字声明的变量:
let x = 2; // 合法
let x = 3; // 不合法
{
let x = 4; // 合法
let x = 5; // 不合法
}
在相同的作用域或块级作用域中,不能使用 var 关键字来重置 let 关键字声明的变量:
let x = 2; // 合法
var x = 3; // 不合法
{
let x = 4; // 合法
var x = 5; // 不合法
}
let 关键字在不同作用域,或不同块级作用域中是可以重新声明赋值的:
let x = 2; // 合法
{
let x = 3; // 合法
}
{
let x = 4; // 合法
}
const 关键字
const 用于声明一个或多个常量,声明时必须进行初始化,且初始化后值不可再修改:
const PI = 3.1415926
pI = 3.14 //出错
const定义常量与使用let 定义的变量相似及不同:
- 二者都是块级作用域
- 都不能和它所在作用域内的其他变量或函数拥有相同的名称
两者还有以下两点区别:
- const声明的常量必须初始化,而let声明的变量不用
- const 定义常量的值不能通过再赋值修改,也不能再次声明。而 let 定义的变量值可以修改。
并非真正的常量
const 的本质: const 定义的变量并非常量,并非不可变,它定义了一个常量引用一个值。使用 const 定义的对象或者数组,其实是可变的。下面的代码并不会报错:
// 创建常量对象
const car = {type:"Fiat", model:"500", color:"white"};
// 修改属性:
car.color = "red";
// 添加属性
car.owner = "Johnson";
但是我们不能对常量对象重新赋值:
实例
const car = {type:"Fiat", model:"500", color:"white"}; car = {type:"Volvo", model:"EX60", color:"red"}; // 错误
注意:对于对象和数组来说,const定义的可以对属性进行修改,但是不能对对象重新赋值
重置变量
使用 var 关键字声明的变量在任何地方都可以修改:
实例
var x = 2; // 合法 var x = 3; // 合法 x = 4; // 合法
在相同的作用域或块级作用域中,不能使用 const 关键字来重置 var 和 let关键字声明的变量:
var x = 2; // 合法
const x = 2; // 不合法
{
let x = 2; // 合法
const x = 2; // 不合法
}
在相同的作用域或块级作用域中,不能使用 const 关键字来重置 const 关键字声明的变量:
const x = 2; // 合法
const x = 3; // 不合法
x = 3; // 不合法
var x = 3; // 不合法
let x = 3; // 不合法
{
const x = 2; // 合法
const x = 3; // 不合法
x = 3; // 不合法
var x = 3; // 不合法
let x = 3; // 不合法
}
const 关键字在不同作用域,或不同块级作用域中是可以重新声明赋值的:
const x = 2; // 合法
{
const x = 3; // 合法
}
{
const x = 4; // 合法
}
变量提升
JavaScript var 关键字定义的变量可以在使用后声明,也就是变量可以先使用再声明(JavaScript 变量提升)。
实例
carName = "Volvo"; // 这里可以使用 carName 变量 var carName;
const 关键字定义的变量则不可以在使用后声明,也就是变量需要先声明再使用。
carName = "Volvo"; // 在这里不可以使用 carName 变量
const carName = "Volvo";
几点总结:
使用var关键字声明的全局作用域变量属于window对象。
使用let关键字声明的全局作用域变量不属于window对象。
使用var关键字声明的变量在任何地方都可以修改。
在相同的作用域或块级作用域中,不能使用let关键字来重置var关键字声明的变量。
在相同的作用域或块级作用域中,不能使用let关键字来重置let关键字声明的变量。
let关键字在不同作用域,或不用块级作用域中是可以重新声明赋值的。
在相同的作用域或块级作用域中,不能使用const关键字来重置var和let关键字声明的变量。
在相同的作用域或块级作用域中,不能使用const关键字来重置const关键字声明的变量
const 关键字在不同作用域,或不同块级作用域中是可以重新声明赋值的:
var关键字定义的变量可以先使用后声明。
let关键字定义的变量需要先声明再使用。
const关键字定义的常量,声明时必须进行初始化,且初始化后不可再修改。
javascript:void(0) 含义
我们经常会使用到 javascript:void(0) 这样的代码,那么在 JavaScript 中 javascript:void(0) 代表的是什么意思呢?
javascript:void(0) 中最关键的是 void 关键字, void 是 JavaScript 中非常重要的关键字,该操作符指定要计算一个表达式但是不返回值。
语法格式如下:
<head>
<script type="text/javascript">
<!--
void func()
javascript:void func()
或者
void(func())
javascript:void(func())
//-->
</script>
</head>
href="#"与href="javascript:void(0)"的区别
# 包含了一个位置信息,默认的锚是#top 也就是网页的上端。
而javascript:void(0), 仅仅表示一个死链接。
在页面很长的时候会使用 # 来定位页面的具体位置,格式为:# + id。
如果你要定义一个死链接请使用 javascript:void(0) 。
注:void()仅仅是代表不返回任何值,但是括号内的表达式还是要运行,如
void(alert("Warnning!"))