JavaScript基础知识学习-2

196 阅读21分钟

Boolean

JavaScript 布尔(逻辑)代表两个值之一:true 或 false

var x = 0;
Boolean(x);       // 返回 false
var x = -1;
Boolean(x);       // 返回 true
var x = "";
Boolean(x);       // 返回 false
var x = "1";
Boolean(x);       // 返回 true

NaN 的布尔值是 false

var x = 10 / "H";
Boolean(x);       // 返回 false

布尔可以是对象

通常 JavaScript 布尔是由字面量创建的原始值:

var x = false

但是布尔也可以通过关键词 new 作为对象来定义:

var y = new Boolean(false)
var x = false;
var y = new Boolean(false);

// typeof x 返回 boolean
// typeof y 返回 object

不要创建布尔对象。它会拖慢执行速度。

new 关键词会使代码复杂化,并产生某些意想不到的结果:

当使用 == 运算符时,相等的布尔是相等的:

var x = false;             
var y = new Boolean(false);

// (x == y) 为 true,因为 x 和 y 拥有相等的值
//当使用 `===` 运算符时,相等的布尔是不相等的,因为 `===` 运算符需要在类型和值两方面同时相等。

或者甚至更糟。对象无法进行比较:

var x = new Boolean(false);             
var y = new Boolean(false);

// (x == y) 为 false,因为对象无法比较

JavaScript 比较


比较和逻辑运算符用于测试 true 或 false


比较运算符

  • ==
  • ===
  • !=
  • !===

条件(三元)运算符

variablename = (condition) ? value1:value2

JavaScript Switch 语句

Switch case 使用严格比较(===)。

值必须与要匹配的类型相同。

只有操作数属于同一类型时,严格比较才能为 true。
也就是说匹配的值不能是对象,只能是基础值。

在这个例子中,x 将不匹配:

var x = "0";
switch (x) {
  case 0:
    text = "Off";
    break;
  case 1:
    text = "On";
    break;
  default:
    text = "No value found";
}

JavaScript Loop 循环

For

语句 1

通常,您会使用语句 1 来初始化循环中所使用的的变量(i = 0)。

但情况并不总是这样,JavaScript 不会在意。语句 1 是可选的。

您可以在语句 1 中初始化多个值(由逗号分隔):

var cars = ["BMW", "Volvo", "porsche", "Ford"];
var i, len, text;
for (i = 0, len = cars.length, text = ""; i < len; i++) {
    text += cars[i] + "<br>";
}

而且您还可以省略语句 1(比如在循环开始前设置好值):

var cars = ["BMW", "Volvo", "porsche", "Ford"];
var i = 0;
var len = cars.length;
var text = "";
for (; i < len; i++) {
    text += cars[i] + "<br>";
}

For/In 循环

For In 遍历数组:

var person = {fname:"Bill", lname:"Gates", age:62}; 

var text = "";
var x;
for (x in person) {
    text += person[x];
}

例子解释

  • for in 循环遍历 person 对象
  • 每次迭代返回一个 (x)
  • 键用于访问键的
  • 键的值为 person[x]

For In 遍历数组:

const numbers = [45, 4, 9, 16, 25];

let txt = "";
for (let x in numbers) {
  txt += numbers[x];
}

如果索引顺序很重要,请不要在数组上使用 for in
索引顺序依赖于实现,可能不会按照您期望的顺序访问数组值。
当顺序很重要时,最好使用 for 循环、for of 循环或 Array.forEach()

Array.forEach()

forEach() 方法为每个数组元素调用一次函数(回调函数)。

const numbers = [45, 4, 9, 16, 25];

let txt = "";
numbers.forEach(myFunction);

function myFunction(value, index, array) {
  txt += value;
}

请注意,该函数采用 3 个参数:

  • 项目值
  • 项目索引
  • 数组本身

上面的例子仅使用 value 参数。可以改写为:

const numbers = [45, 4, 9, 16, 25];

let txt = "";
numbers.forEach(myFunction);

function myFunction(value) {
  txt += value;
}

For Of

JavaScript for of 语句循环遍历可迭代对象的值。

它允许您循环遍历可迭代的数据结构,例如数组、字符串、映射、节点列表等:

for (variable of iterable) {
  // code block to be executed
}

variable - 对于每次迭代,下一个属性的值都会分配给变量。变量可以用 const、let 或 var 声明。

iterable - 具有可迭代属性的对象。

浏览器支持

For/of 在 2015 年被添加到 JavaScript (ES6)

Safari 7 是第一个支持 for of 的浏览器:

ChromeIEFirefoxSafariOpera
Chrome 38Edge 12Firefox 51Safari 7Opera 25
2014 年 10 月2015 年 7 月2016 年 10 月2013 年 10 月2014 年 10 月

Internet Explorer 不支持 For/of

遍历数组

const cars = ["BMW", "Volvo", "Mini"];

let text = "";
for (let x of cars) {
  text += x;
}

遍历字符串

let language = "JavaScript";

let text = "";
for (let x of language) {
text += x;
}

While 循环


只要条件为 true,循环能够一直执行代码块。


语法

while (条件) {
    要执行的代码块
}

在下面的例子中,循环中的代码将运行,一遍又一遍,只要变量(i)小于 10:

var text = "";
var i = 0;
while (i < 10) {
    text += "<br>数字是 " + i;
    i++;
}

Do/While 循环

do/while 循环是 while 循环的变体。在检查条件是否为真之前,这种循环会执行一次代码块,然后只要条件为真就会重复循环。 while:先检查再执行 do/while:先执行一次再检查调价

语法

do {
    要执行的代码块
}

while (条件);

下面的例子使用了 do/while 循环。该循环会执行至少一次,即使条件为 false,因为代码块会在条件测试之前执行:

do {
    text += "The number is " + i;
    i++;
 }
while (i < 10);

JavaScript typeof

在 JavaScript 中有 5 种不同的可以包含值的数据类型:

  • string
  • number
  • boolean
  • object
  • function

有 6 种类型的对象:

  • Object
  • Date
  • Array
  • String
  • Number
  • Boolean

以及 2 种不能包含值的数据类型:

  • null
  • undefined

typeof 运算符

您可以使用 typeof 运算符来确定 JavaScript 变量的数据类型。

typeof "Bill"                 // 返回 "string"
typeof 3.14                   // 返回 "number"
typeof NaN                    // 返回 "number"
typeof false                  // 返回 "boolean"
typeof [1,2,3,4]              // 返回 "object"
typeof {name:'Bill', age:19}  // 返回 "object"
typeof new Date()             // 返回 "object"
typeof function () {}         // 返回 "function"
typeof myCar                  // 返回 "undefined" *
typeof null                   // 返回 "object"

请注意:

  • NaN 的数据类型是数字
  • 数组的数据类型是对象
  • 日期的数据类型是对象
  • null 的数据类型是 object
  • 未定义变量的数据类型为 undefined *
  • 未赋值的变量的数据类型也是 undefined *

您无法使用 typeof 来确定 JavaScript 对象是否是数组(或日期)。

typeof {name:'Bill', age:19} // 返回 "object"
typeof [1,2,3,4]             // 返回 "object"(非 "array",请注意下面的例子)
typeof null                  // 返回 "object"
typeof function myFunc(){}   // 返回 "function

typeof 运算符会为数组返回 "object",因为在 JavaScript 中数组是对象。

constructor 属性

constructor 属性返回所有 JavaScript 变量的构造函数。

"Bill".constructor                // 返回 function String()  {[native code]}
(3.14).constructor                // 返回 function Number()  {[native code]}
false.constructor                 // 返回 function Boolean() {[native code]}
[1,2,3,4].constructor             // 返回 function Array()   {[native code]}
{name:'Bill',age:19}.constructor  // 返回 function Object()  {[native code]}
new Date().constructor            // 返回 function Date()    {[native code]}
function () {}.constructor        // 返回 function Function(){[native code]}

您可以检查 constructor 属性以确定对象是否为数组(包含 "Array" 一词):

function isArray(myArray) {
  return myArray.constructor.toString().indexOf("Array") > -1;
}

或者更简单,您可以检查对象是否为数组函数

function isArray(myArray) {
  return myArray.constructor === Array;
}

您可以检查 constructor 属性以确定对象是否为日期(包含 "Date" 一词):

function isDate(myDate) {
  return myDate.constructor.toString().indexOf("Date") > -1;
}

或者更简单,您可以检查对象是否为日期函数

function isDate(myDate) {
  return myDate.constructor === Date;
}

Undefined

在 JavaScript 中,没有值的变量的值是 undefined。类型也是 undefined

let car;    // 值是 undefined,类型也是 undefined。
car = undefined;    // 值是 undefined,类型也是 undefined。
let car = "";    // 值是 "",类型是 "string"

Null

在 JavaScript 中 null 即是“无”。它应该是不存在的东西。

不幸的是,在 JavaScript 中,null 的数据类型是一个对象。

你可以认为它是 JavaScript 中的一个 bug,typeof null 是一个对象。类型应为 null

您可以通过将对象设置为 null 来清空对象:

let person = {firstName:"Bill", lastName:"Gates", age:19, eyeColor:"blue"};
person = null;    // 现在值为 null,但类型仍然是对象
let person = {firstName:"Bill", lastName:"Gates", age:19, eyeColor:"blue"};
person = undefined;   // 现在值和类型都是未定义

undefined 与 null 的区别

undefined 和 null 值相等但类型不同:

typeof undefined           // undefined
typeof null                // object

null === undefined         // false
null == undefined          // true

JavaScript 类型转换


Number() 转换数值,String() 转换字符串,Boolean() 转换布尔值。


JavaScript 数据类型

JavaScript 中有五种可包含值的数据类型:

  • 字符串(string)
  • 数字(number)
  • 布尔(boolean)
  • 对象(object)
  • 函数(function)

有三种对象类型:

  • 对象(Object)
  • 日期(Date)
  • 数组(Array)

同时有两种不能包含值的数据类型:

  • null
  • undefined

把数值转换为字符串

全局方法 String() 能够把数字转换为字符串。

它可用于任意类型的数字、文字、变量或表达式:

String(x)         // 从数值变量 x 返回字符串
String(123)       // 从数值文本 123 返回字符串
String(100 + 23)  // 从表达式中的数值返回字符串

数字方法 toString() 同理。

x.toString()
(123).toString()
(100 + 23).toString()

把日期转换为字符串

String(Date())      "demo1">// 返回 "Thu Sep 15 2022 14:37:50 GMT+0800 (中国标准时间)"
Date().toString()   "demo2">// 返回 "Thu Sep 15 2022 14:37:50 GMT+0800 (中国标准时间)"

把字符串转换为数值

全局方法 Number() 可把字符串转换为数字。

包含数字的字符串(比如 "3.14")转换为数字(比如 3.14)。

空的字符串转换为 0。

其他字符串将转换为 NaN(Not a number,不是数字)。

Number("3.14")    // 返回 3.14
Number(" ")       // 返回 0
Number("")        // 返回 0
Number("99 88")   // 返回 NaN

一元 + 运算符

一元的 + 运算符*可用于把变量转换为数字:

var y = "5";      // y 是字符串
var x = + y;      // x 是数字

如果无法转换变量,则仍会成为数字,但是值为 NaN(Not a number):

var y = "Bill";   // y 是字符串
var x = + y;      // x 是数字 (NaN)

把布尔转换数值

全局方法 Number() 也可把布尔转换为数字。

Number(false)     // 返回 0
Number(true)      // 返回 1

把日期转换为数字

全局方法 Number() 可用于把日期转换为数字。

d = new Date();
Number(d)          "demo3">// 返回 1663223870446

日期方法 getTime() 同理。

d = new Date();
d.getTime()        "demo4">// 返回 1663223870446

如果 JavaScript 尝试操作一种“错误”的数据类型,它会试图将该值转换为“正确”的类型。

结果并不总是你所期望的:

5 + null    // 返回 5         因为 null 被转换为 0
"5" + null  // 返回 "5null"   因为 null 被转换为  "null"
"5" + 2     // 返回 52        因为 2 被转换为 "2"
"5" - 2     // 返回 3         因为 "5" 被转换为 5
"5" * "2"   // 返回 10        因为 "5" 和 "2" 被转换为 52

自动字符串转换

当您试图“输出”对象或变量时,JavaScript 自动调用变量的 toString() 函数:

document.getElementById("demo").innerHTML = myVar;

// 如果 myVar = {name:"Fjohn"}  // toString 转换为 "[object Object]"
// 如果 myVar = [1,2,3,4]       // toString 转换为 "1,2,3,4"
// 如果 myVar = new Date()      // toString 转换为 "Thu Sep 15 2022 14:37:50 GMT+0800 (中国标准时间)"

数字和布尔也会被转换,但并不明显:

// 如果 myVar = 123             // toString 转换为 "123"
// 如果 myVar = true            // toString 转换为 "true"
// 如果 myVar = false           // toString 转换为 "false"
原始值转换为数字转换为字符串转换为逻辑
false0"false"false
true1"true"true
00"0"false
11"1"true
"0"0"0"true
"000"0"000"true
"1"1"1"true
NaNNaN"NaN"false
InfinityInfinity"Infinity"true
-Infinity-Infinity"-Infinity"true
""0""false
"20"20"20"true
"twenty"NaN"twenty"true
[ ]0""true
[20]20"20"true
[10,20]NaN"10,20"true
["twenty"]NaN"twenty"true
["ten","twenty"]NaN"ten,twenty"true
function(){}NaN"function(){}"true
{ }NaN"[object Object]"true
null0"null"false
undefinedNaN"undefined"false

引号中的值指示字符串值。

红色的值指示了(某些)程序员也许不希望的值。

JavaScript 正则表达式


正则表达式是构成搜索模式的字符序列。

该搜索模式可用于文本搜索和文本替换操作。


什么是正则表达式?

正则表达式是构成 搜索模式(search pattern) 的字符序列。

当您搜索文本中的数据时,您可使用搜索模式来描述您搜索的内容。

正则表达式可以是单字符,或者更复杂的模式。

正则表达式可用于执行所有类型的文本搜索文本替换操作。

语法

/pattern/modifiers;

实例

var patt = /w3school/i;

例子解释:

/w3school/i 是一个正则表达式。

w3school 是模式(pattern)(在搜索中使用)。

i 是修饰符(把搜索修改为大小写不敏感)。

使用字符串方法

在 JavaScript 中,正则表达式常用于两个字符串方法search() 和 replace()

search() 方法使用表达式来搜索匹配,然后返回匹配的位置。

replace() 方法返回模式被替换处修改后的字符串。

在字符串方法 search() 中使用正则表达式

实例

使用正则表达式执行搜索字符串中 "w3school" 的大小写不敏感的搜索:

var str = "Visit W3School";
var n = str.search(/w3school/i); 

使用字符串方法 replace() 处理字符串

使用大小写不明的正则表达式以 W3school 来替换字符串中的 Microsoft:

var str = "Visit Microsoft!";
var res = str.replace(/microsoft/i, "W3School"); 

正则表达式修饰符

修饰符可用于大小写不敏感的更全局的搜素:

修饰符描述
i执行对大小写不敏感的匹配。
g执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
m执行多行匹配。

正则表达式模式

括号用于查找一定范围的字符串:

表达式描述试一试
[abc]查找方括号之间的任何字符。试一试
[0-9]查找任何从 0 至 9 的数字。试一试
(xy)查找由分隔的任何选项。试一试

元字符(Metacharacter) 是拥有特殊含义的字符:

元字符描述试一试
\d查找数字。试一试
\s查找空白字符。试一试
\b匹配单词边界。试一试
\uxxxx查找以十六进制数 xxxx 规定的 Unicode 字符。试一试

Quantifiers 定义量词:

量词描述试一试
n+匹配任何包含至少一个 n 的字符串。试一试
n*匹配任何包含零个或多个 n 的字符串。试一试
n?匹配任何包含零个或一个 n 的字符串。试一试

使用 test()

test() 是一个正则表达式方法。

它通过模式来搜索字符串,然后根据结果返回 true 或 false。

下面的例子搜索字符串中的字符 "e":

/e/.test("The best things in life are free!");

由于字符串中有一个 "e",以上代码的输出将是:

true

使用 exec()

exec() 方法是一个正则表达式方法。

它通过指定的模式(pattern)搜索字符串,并返回已找到的文本。

如果未找到匹配,则返回 null。

下面的例子搜索字符串中的字符 "e":

实例

/e/.exec("The best things in life are free!");

由于字符串中有一个 "e",以上代码的输出将是:

e

JavaScript 错误 - Throw 和 Try to Catch


try 语句使您能够测试代码块中的错误。

catch 语句允许您处理错误。

throw 语句允许您创建自定义错误。

finally 使您能够执行代码,在 try 和 catch 之后,无论结果如何。


JavaScript try 和 catch

try 语句允许您定义一个代码块,以便在执行时检测错误。

catch 语句允许你定义一个要执行的代码块,如果 try 代码块中发生错误。

JavaScript 语句 try 和 catch 成对出现:

try {
     供测试的代码块
}
 catch(err) {
     处理错误的代码块
} 

throw 语句

throw 语句允许您创建自定义错误。

从技术上讲您能够抛出异常(抛出错误)

异常可以是 JavaScript 字符串、数字、布尔或对象:

throw "Too big";    // 抛出文本
throw 500;          //抛出数字

如果把 throw 与 try 和 catch 一同使用,就可以控制程序流并生成自定义错误消息。

<!DOCTYPE html>
<html>
<body>

<p>请输入 5 - 10 之间的数字:</p>

<input id="demo" type="text">
<button type="button" onclick="myFunction()">测试输入</button>
<p id="message"></p>

<script>
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) {
        //判处的文字都会走到这里,变为err。
        message.innerHTML = "输入是 " + err;
    }
}
</script>

</body>
</html> 

finally 语句

finally 语句允许您在 try 和 catch 之后执行代码,无论结果:

try {
     // 供测试的代码块
}
 catch(err) {
     // 处理错误的代码块
} 
finally {
     // 无论结果如何都执行的代码块
}

Error 对象

JavaScript 拥有当错误发生时提供错误信息的内置 error 对象。

error 对象提供两个有用的属性:name 和 message

Error 对象属性

属性描述
name设置或返回错误名
message设置或返回错误消息(一条字符串)

Error Name Values

error 的 name 属性可返回六个不同的值:

错误名描述
EvalError已在 eval() 函数中发生的错误
RangeError已发生超出数字范围的错误
ReferenceError已发生非法引用
SyntaxError已发生语法错误
TypeError已发生类型错误
URIError在 encodeURI() 中已发生的错误

Eval 错误

EvalError 指示 eval() 函数中的错误。

更新版本的 JavaScript 不会抛出任何 EvalError。请使用 SyntaxError 代替。

范围错误

RangeError 会在您使用了合法值的范围之外的数字时抛出。

例如:您不能将数字的有效位数设置为 500。

实例

var num = 1;
try {
    num.toPrecision(500);   // 数无法拥有 500 个有效数
 }
catch(err) {
    document.getElementById("demo").innerHTML = err.name;
} 

引用错误

假如您使用(引用)了尚未声明的变量,则 ReferenceError 会被抛出:

实例

var x;
try {
    x = y + 1;   // y 无法被引用(使用)
 }
catch(err) {
    document.getElementById("demo").innerHTML = err.name;
} 

语法错误

假如您计算带语法错误的代码,会 SyntaxError 被抛出:

实例

try {
    eval("alert('Hello)");   // 缺少 ' 会产生错误
}
catch(err) {
     document.getElementById("demo").innerHTML = err.name;
} 

类型错误

假如您使用的值不在期望值的范围之内,则 TypeError 被抛出:

实例

var num = 1;
try {
    num.toUpperCase();   // 您无法将数字转换为大写
 }
catch(err) {
    document.getElementById("demo").innerHTML = err.name;
} 

URI 错误

假如您在 URI 函数中使用非法字符,则 URIError 被抛出:

实例

try {
    decodeURI("%%%");   // 您无法对这些百分号进行 URI 编码
 }
catch(err) {
    document.getElementById("demo").innerHTML = err.name;
} 

JavaScript Hoisting


提升(Hoisting)是 JavaScript 将声明移至顶部的默认行为。


**仅限于var声明且不初始化的对象**

JavaScript 声明会被提升

在 JavaScript 中,可以在使用变量之后对其进行声明。

换句话说,可以在声明变量之前使用它。

例子 1 与例子 2 的结果相同:

例子 1

x = 5; // 把 5 赋值给 x
 
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x;                     // 在元素中显示 x

var x; // 声明 x

例子 2

var x; // 声明 x
x = 5; // 把 5 赋值给 x

elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x;                     // 在元素中显示 x

为了理解这一点,您必须理解术语 "hoisting"。

Hoisting 是 JavaScript 将所有声明提升到当前作用域顶部的默认行为(提升到当前脚本或当前函数的顶部)。

let 和 const 关键字

用 let 或 const 声明的变量和常量不会被提升!

JavaScript 初始化不会被提升

JavaScript 只提升声明,而非初始化。

var x = 5; // 初始化 x
 
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = "x is " + x + " and y is " + y;  // x is 5 and y is undefined
 
var y = 7; // 初始化 y 

这个例子 y虽然说Hoisting(提升)了, 但是y初始化的晚了。他需要在使用前初始化。

var x = 5; // 初始化 x
var y;     // 声明 y
 
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = "x is " + x + " and y is " + y;  // x is 5 and y is 

y = 7;    // 把 7 赋值给 y

在顶部声明您的变量!

Hoisting(对很多开发者来说)是 JavaScript 的一种未知的或被忽视的行为。

如果开发者不理解 hoisting,程序也许会包含 bug(错误)。

为了避免 bug,请始终在每个作用域的开头声明所有变量。

由于这就是 JavaScript 解释代码的方式,请保持这个好习惯。

严格模式中的 JavaScript 不允许在未被声明的情况下使用变量。

JavaScript 严格模式


"use strict"; 定义 JavaScript 代码应该以“严格模式”执行。


"use strict" 指令

"use strict" 是 JavaScript 1.8.5 中的新指令(ECMAScript version 5)。

它不算一条语句,而是一段文字表达式,更早版本的 JavaScript 会忽略它。

"use strict"; 的作用是指示 JavaScript 代码应该以“严格模式”执行。

在严格模式中,您无法,例如,使用未声明的变量。

以下版本的浏览器支持严格模式:

  • 版本 10 以后的 IE
  • 版本 4 以后的 Firefox
  • 版本 13 以后的 Chrome
  • 版本 5.1 以后的 Safari
  • 版本 12 以后的 Opera

声明严格模式

通过在脚本或函数的开头添加 "use strict"; 来声明严格模式。

在脚本开头进行声明,拥有全局作用域(脚本中的所有代码均以严格模式来执行):

实例

"use strict";
x = 3.14;       // 这会引发错误,因为 x 尚未声明
"use strict";
myFunction();

function myFunction() {
     y = 3.14;   // 这会引发错误,因为 y 尚未声明
}

在函数中声明严格模式,拥有局部作用域(只有函数中的代码以严格模式执行):

x = 3.14;       // 这不会引发错误
myFunction();

function  myFunction() {
	"use strict";
	 y = 3.14;   // 这会引发错误
}

严格模式中不允许的事项

在不声明变量的情况下使用变量,是不允许的:

"use strict";
x = 3.14;                // 这将引发错误

对象也是变量

在不声明对象的情况下使用对象也是不允许的:

"use strict";
x = {p1:10, p2:20};      // 这将引发错误

删除变量(或对象)是不允许的:

"use strict";
var x = 3.14;
delete x;                // 这将引发错误

删除函数是不允许的:

"use strict";
function x(p1, p2) {}; 
delete x;                 // 这将引发错误

重复参数名是不允许的:(也不会有人这么做吧)

"use strict";
function x(p1, p1) {};   // 这将引发错误

八进制数值文本是不允许的:

"use strict";
var x = 010;             // 这将引发错误

转义字符是不允许的:

"use strict";
var x = \010;            // 这将引发错误

写入只读属性是不允许的:

"use strict";
var obj = {};
Object.defineProperty(obj, "x", {value:0, writable:false});

obj.x = 3.14;            // 这将引发错误

写入只能获取的属性是不允许的:

"use strict";
var obj = {get x() {return 0} };

obj.x = 3.14;            // 这将引发错误

删除不可删除的属性是不允许的:

"use strict";
delete Object.prototype; // 这将引发错误

字符串 "eval" 不可用作变量:

"use strict";
var eval = 3.14;         // 这将引发错误

字符串 "arguments" 不可用作变量:

"use strict";
var arguments = 3.14;    // 这将引发错误

with 语句是不允许的:

"use strict";
with (Math){x = cos(2)}; // 这将引发错误

处于安全考虑,不允许 eval() 在其被调用的作用域中创建变量:

"use strict";
eval ("var x = 2");
alert (x);               // 这将引发错误

对未来的保障

严格模式中不允许使用为未来预留的关键词。它们是:

  • implements
  • interface
  • let
  • package
  • private
  • protected
  • public
  • static
  • yield
"use strict";
var public = 1500;      // 这将引发错误

"use strict" 指令只能在脚本或函数的开头被识别。

如果没看到这么多不被允许,我还不知道某些功能默认是允许的。

"use strict" 指令只能在脚本或函数的开头被识别。

JavaScript this 关键词

实例

var person = {
  firstName: "Bill",
  lastName : "Gates",
  id       : 678,
  fullName : function() {
    return this.firstName + " " + this.lastName;
  }
};

this 是什么?

JavaScript this 关键词指的是它所属的对象。

它拥有不同的值,具体取决于它的使用位置:

  • 在方法中,this 指的是所有者对象。
  • 单独的情况下,this 指的是全局对象。
  • 在函数中,this 指的是全局对象。
  • 在函数中,严格模式下,this 是 undefined。
  • 在事件中,this 指的是接收事件的元素。

像 call() 和 apply() 这样的方法可以将 this 引用到任何对象。

方法中的 this

在对象方法中,this 指的是此方法的“拥有者”。

在上面的例子中,this 指的是 person 对象。

person 对象是 fullName 方法的拥有者。

fullName : function() {
  return this.firstName + " " + this.lastName;
}

单独的 this

在单独使用时,拥有者是全局对象,因此 this 指的是全局对象。

在浏览器窗口中,全局对象是 [object Window]

实例

var x = this;

在严格模式中,如果单独使用,那么 this 指的是全局对象 [object Window]

实例

"use strict";
var x = this;

事件处理程序中的 this

在 HTML 事件处理程序中,this 指的是接收此事件的 HTML 元素:

实例

<button onclick="this.style.display='none'">
  点击来删除我!
</button>

对象方法绑定

在此例中,this 是 person 对象(person 对象是该函数的“拥有者”):

实例

var person = {
  firstName: "Bill",
  lastName : "Gates",
  id       : 678,
  fullName : function() {
    return this.firstName + " " + this.lastName;
  }
};

换句话说,this.firstName 意味着 this(person)对象的 firstName 属性。

JavaScript 箭头函数

ES6 中引入了箭头函数。

箭头函数允许我们编写更短的函数

语法

之前:

hello = function() {
  return "Hello World!";
}

之后

hello = () => {
  return "Hello World!";
}

确实变短了!如果函数只有一个语句,并且该语句返回一个值,则可以去掉括号和 return 关键字:
箭头函数默认返回值:

似曾相识的感觉,但是又想不起来是哪里。

hello = () => "Hello World!";

注释:这仅在函数只有一条语句时才有效。

如果您有参数,则将它们传递到括号内:

带参数的箭头函数:

hello = (val) => "Hello " + val;

事实上,如果只有一个参数,您也可以略过括号:

不带括号的箭头函数:

hello = val => "Hello " + val;

this 怎么办?还有点小复杂!

与常规函数相比,箭头函数对 this 的处理也有所不同。

简而言之,使用箭头函数没有对 this 的绑定。

在常规函数中,关键字 this 表示调用该函数的对象,可以是窗口、文档、按钮或其他任何东西。

对于箭头函数,this 关键字始终表示定义箭头函数的对象。

让我们看两个例子来理解其中的差异。

这两个例子都调用了两次方法,第一次是在页面加载时,第二次是在用户单击按钮时。

第一个例子使用常规函数,第二个例子使用箭头函数。

结果显示第一个例子返回两个不同的对象(window 和 button),第二个例子返回两次 window 对象,因为 window 对象是函数的“所有者”。

实例1

对于常规函数,this 表示调用该函数的对象:

// 常规函数:
hello = function() {
  document.getElementById("demo").innerHTML += this;
}

// window 对象调用该函数:
window.addEventListener("load", hello);//[object Window]

// button 对象调用该函数:
document.getElementById("btn").addEventListener("click", hello);//[object HTMLButtonElement]

实例

用了箭头函数,则 this 表示函数的拥有者:

// 箭头函数:
hello = () => {
  document.getElementById("demo").innerHTML += this;
}

// window 对象调用该函数:
window.addEventListener("load", hello);//[object Window]

// button 对象调用该函数:
document.getElementById("btn").addEventListener("click", hello);//[object Window]

浏览器支持

下表注明了首个完全支持 JavaScript 箭头函数的浏览器版本:

ChromeIEFirefoxSafariOpera
Chrome 45Edge 12Firefox 22Safari 10Opera 32
2015 年 9 月2015 年 7 月2013 年 5 月2016 年 9 月2015 年 9 月