本文目录
strict模式
为了修补JavaScript设计缺陷,ECMA在规范中推出strict模式。
'use strict' //strict模式启用方式,注意:需要写在JavaScript代码第一行
字符串换行
此方法是ES6的标准,可以在字符串中使用’\n’达到一样的效果。
let temp = `这是
测试
换行
字符串`
模板字符串
此方法是ES6的标准,目的是拼接字符串,可以在字符串中使用’+'达到一样的效果。
//'+'拼接
let key = '字符串'
let value = '拼接'
let result = '测试:' + key + '\t' + value // 测试:字符串 拼接
//模板字符串
let key = '字符串'
let value = '拼接'
let result = `测试:${key}\t${value}` // 测试:字符串 拼接
数组的遍历
let arr = ['a', 'b', 'c']; //定义一个简单的数组
//方法一 遍历下标
for (let i = 0 ; i < arr.length ; i++) {
console.log(arr[i]) // a b c
}
//方法二 for..in
for (let temp in arr) {
console.log(temp) // 0 1 2
}
注意:for…in方法输出的是实际上是对象的属性名称。而数组实际上是一个对象,每个元素的索引被认为是属性。所以在进行数组遍历的时候不建议使用for…in方法
//方法三 for...of
for (let temp1 of arr) {
console.log(temp1) // a b c
}
注意:for…of修复了for…in出现的问题,遍历是对象本身。
//方法四 foreach
arr.forEach((value, index, array) => console.log(`${value} --> ${index} --> ${array}`))
//输出结果
a --> 0 --> a,b,c
b --> 1 --> a,b,c
c --> 2 --> a,b,c
函数
- arguments
JavaScript在函数中有默认有一个关键字arguments,只在函数内部生效,并且指向当前函数调用者传入的所有参数。
let abs = function (x) {
if (arguments.length === 0) {
throw "No arguments";
}
for (let i = 0 ; i < arguments.length; i ++) {
console.log(arguments[i]);
}
if (typeof x !== 'number') {
throw 'Not a number';
}
return x > 0 ? x : -x;
}
let result = abs(1, 2, 3, 4, 'asdf');
console.log(result) // 1 2 3 4 'asdf' 1
注意:在JavaScript中函数传入的参数与函数接收的参数个数可以不一致。
- rest
由于JavaScript中函数传入的参数与函数接收的参数个数可以不一致,导致可能需要对多余的参数进行处理,所以引入rest参数用于获取额外的参数。多余的参数以数组的形式传递给变量rest,但是不一定接收多余参数的变量必须命名为rest。
let foo = function (x, y, ...test) {
console.log(x);
console.log(y);
console.log(test)
}
foo(1, 2, 'a', 'b', 'c', 'd');
全局作用域
在JavaScript中默认有一个全局对象window。访问全局变量是,直接使用变量名访问和使用window.{变量名}访问的效果是一致的。但是需要注意的是,ES6引入的let变量解决的块级作用域的问题。使用let和var对全局变量进行定义,访问的效果是不一样的。使用let定义的变量,使用window.{变量名}访问的结果是undefined。
'use strict'
let temp1= 'JavaScript';
alert(temp1); // 'JavaScript'
alert(window.temp1); // undefined
var temp2 = 'Learn JavaScript';
alert(temp2); // 'JavaScript'
alert(window.temp2); // 'JavaScript'
全局变量会被绑定到window上,不同的JavaScript文件如果使用了相同的全局变量,或者定义了相同名字的顶层函数,都会造成命名冲突,并且很难被发现。减少冲突的一个方法是自定义一个全局变量,并绑定自己的所有变量和函数。
'use strict'
let myWindow = {};
myWindow.name = 'myScript';
myWindow.version = 1.0;
console.log(`${myWindow.name} ---> ${myWindow.version}`) // myScript ---> 1
myWindow.foo = function () {
console.log("myWindow function");
}
myWindow.foo(); // myWindow function
常量
在ES6之前通常用全部大写的变量来表示“这是一个常量,不要修改它的值”,ES6标准引入了新的关键字const来定义常量,const与let都具有块级作用域。
'use strict'
const PI = 3.14;
console.log(PI);
PI = 3; //Attempt to assign to const or readonly variable
console.log(PI);
解构赋值
在ES6中,可以使用解构赋值直接对多个变量同时赋值,该方法适用于数据,也适用于对象。
'use strict'
let Person = {
name: "test",
age: 18,
school: 'middle school',
address: {
city: 'Beijing',
street: 'No.1 Street',
zipcode: '000001'
}
};
let {name:username, age, address:{city, zipcode}} = Person;
console.log(`${username} --> ${age} --> ${city} + ${zipcode}`); //test --> 18 --> Beijing + 000001
在默认情况下,针对对象使用解构赋值需要保证变量名和对象属性名一致,否则会出现undefined的情况。如果需要进行变量名转换,则可以在解构赋值的时候使用对象属性名:自定义变量名。
高阶函数-map/reduce
map:JavaScript的map()方法只定义在Array中,其返回的结果也是Array。
function pow(x){
return x * x;
}
let test = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let result = test.map(pow);
console.log(result); // [ 1, 4, 9, 16, 25, 36, 49, 64, 81 ]
reduce:
function sum(x, y) {
return x + y;
}
let test = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let result = test.reduce(sum);
console.log(result); //45
高阶函数-filter
filter:和map类似作用于Array,其返回值也是一个Array。不同之处在于filter将传入的函数作用于每一个元素,然后根据返回的boolean值决定元素的去留问题。
function foo(x) {
return x % 2 === 0;
}
let test = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let result = test.filter(foo);
console.log(result); //[ 2, 4, 6, 8 ]
filter可以运用于数组的去重。
let test = ['a', 'b', 'c', 'd', 'e', 'b', 'f', 'd'];
let result = test.filter((value, index, array) =>
{
return array.indexOf(value) === index;
}
);
console.log(result); // [ "a", "b", "c", "d", "e", "f" ]
高阶函数-sort
在JavaScript中sort函数默认是按照ASCII进行比较并排序,对于数字和字符串的比较有时会出现异常的结果。
'use strict'
let arr = ["Banana", "apple", "Orange"];
console.log(arr.sort()); // [ "Banana", "Orange", "apple" ]
arr = [1, 20, 10, 2];
console.log(arr.sort()); // [ 1, 10, 2, 20 ]
为了得到符合预期的结果,可以实现自定义的排序方法。
'use strict'
let arr = ["Banana", "apple", "Orange"];
arr.sort((a, b) =>
{
let a1 = a.toUpperCase();
let b1 = b.toUpperCase();
if (a1 > b1) {
return 1;
} else if (a1 < b1) {
return -1;
} else {
return 0;
}
}
);
console.log(arr); // [ "apple", "Banana", "Orange" ]
arr = [1, 20, 10, 2];
arr.sort((a, b) =>
{
if (a > b) {
return 1;
} else if (a < b) {
return -1;
} else {
return 0;
}
}
);
console.log(arr); // [ 1, 2, 10, 20 ]
generator
generator是ES6引入的新数据类型,其看上去类似于函数的定义,作用是返回多次。
例如在进行斐波那契数列计算时,使用函数得到的结果是使用数组进行表示的。
'use strict'
function fibonacci(max) {
let result = [0, 1];
let a = 0,b =1;
while (result.length < max) {
[a, b] = [b, a+b];
result.push(b);
}
return result;
}
console.log(fibonacci(8)); // [ 0, 1, 1, 2, 3, 5, 8, 13 ]
但是如果需要返回每一次产生的数值,使用函数则可能比较难以实现。使用generator则可以较为方便的解决该问题。
function* fibonacci(max) {
let a = 0, b = 1, times = 1;
while (times <= max) {
yield a;
[a, b] = [b, a+b];
times = times + 1;
}
return;
}
let max = 8;
let result = fibonacci(max);
console.log(result);
for (let number of result) {
console.log(number); // [ 0, 1, 1, 2, 3, 5, 8, 13 ]
}
generator使用function*标识,yield表示每次执行返回的值。
正则表达式
\d 数字
\w 字母
\s 空格
* 表示有任意个字符(包含0个)
+ 表示至少有一个字符
? 表示至多有一个字符
{n} 表示有n个字符
{n,m} 表示有n至m个字符
^ 表示行开头
$ 表示行结尾
() 表示分组
/g 全局匹配
/i 忽略大小写
/m 多行匹配
- 字符串匹配
'use strict'
let regExp = /^\d{3}\-\d{3,8}$/;
console.log(regExp.test("001-01000")); // true
console.log(regExp.test("0100-000010101")); // false
console.log(regExp.test("001-1234567")); // true
- 切分字符串
'use strict'
console.log('a b c'.split(" ")); // [ "a", "b", "", "", "c" ]
console.log('a b c'.split(/\s+/)); // [ "a", "b", "c" ]
console.log('a,b, c;;d ;e'.split(/[\s\,\;]+/)); // [ "a", "b", "c", "d", "e" ]
- 字符串分组
let regExp = /^(\d{3})\-(\d{3,8})$/;
console.log(regExp.exec("001-01000")); // [ "001-01000", "001", "01000" ]
console.log(regExp.exec("0100-000010101")); // null
console.log(regExp.exec("001-1234567")); // [ "001-1234567", "001", "1234567" ]
若符合正则表达式,则返回一个数组。其中数组第一元素为原字符串,其余原色为匹配成功的子串。
- 贪婪匹配
正则匹配默认是贪婪匹配,就是匹配尽可能多的字符。加个?就可以让\d+采用非贪婪匹配。
'use strict'
let regExp = /^(\d+)(0*)$/;
console.log(regExp.exec("1101000")); // [ "1101000", "1101000", "" ]
regExp = /^(\d+?)(0*)$/;
console.log(regExp.exec("1101000")); // [ "1101000", "1101", "000" ]
- 全局匹配
全局匹配与普通匹配类似,但是可以多次运行,并且是全局进行匹配。
'use strict'
let regExp = /[a-zA-z]+Script/g;
let test = 'JavaScript, VBScript, JScript and ECMAScript';
console.log(regExp.exec(test)); // [ "JavaScript" ]
console.log(regExp.exec(test)); // [ "VBScript" ]
console.log(regExp.exec(test)); // [ "JScript" ]
console.log(regExp.exec(test)); // [ "ECMAScript" ]
console.log(regExp.exec(test)); // null
序列化
序列化是将JavaScript对象序列化成JSON字符串。
'use strict'
let Person = {
name: "test",
age: 18,
school: 'middle school',
address: {
city: 'Beijing',
street: 'No.1 Street',
zipcode: '000001'
}
};
console.log(JSON.stringify(Person)); // {"name":"test","age":18,"school":"middle school","address":{"city":"Beijing","street":"No.1 Street","zipcode":"000001"}}
//按照缩进显示结果
'use strict'
let Person = {
name: "test",
age: 18,
school: 'middle school',
address: {
city: 'Beijing',
street: 'No.1 Street',
zipcode: '000001'
}
};
console.log(JSON.stringify(Person, null, " "));
//显示结果
{
"name": "test",
"age": 18,
"school": "middle school",
"address": {
"city": "Beijing",
"street": "No.1 Street",
"zipcode": "000001"
}
}
//自定义返回的JSON
'use strict'
let Person = {
name: "test",
age: 18,
school: 'middle school',
address: {
city: 'Beijing',
street: 'No.1 Street',
zipcode: '000001'
},
toJSON: function () {
return {
'Name': this.name,
'Address':this.address
}
}
};
console.log(JSON.stringify(Person)); //{"Name":"test","Address":{"city":"Beijing","street":"No.1 Street","zipcode":"000001"}}
对象与继承
使用class和extends需要浏览器支持ES6。相较于原型继承更接近于Java,对于有Java基础的理解起来更加方便。
'use strict'
class Student {
constructor(name) {
this.name = name;
}
hello() {
console.log(`hello , ${this.name}`);
}
}
let test = new Student("test");
test.hello(); // hello , test
class PrimaryStudent extends Student {
constructor(name, grade) {
super(name);
this.grade = grade;
}
myGrade() {
console.log("at Grade " + this.grade);
}
}
let test1 = new PrimaryStudent("test1", 3);
test1.hello(); // hello , test1
test1.myGrade(); // at Grade 3
浏览器对象
window 窗口
navigator 浏览器
screen 屏幕
location 当前URL
document 当前页面
history 浏览器历史记录,不推荐使用
'use strict'
console.log(`innerHeight=${window.innerHeight} innerWidth=${window.innerWidth} outerHeight=${window.outerHeight} outerWidth=${window.outerWidth}`);
console.log(`appName=${navigator.appName} appVersion=${navigator.appVersion} language=${navigator.language} platform=${navigator.platform}`);
console.log(`height=${screen.height} width=${screen.width} colorDepth=${screen.colorDepth}`);
console.log(`host=${location.host} pathname=${location.pathname} toString=${location.toString()}`)
console.log(`title=${document.title} cookie=${document.cookie}`);
图片预览
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="SimpleJavaScript.js"></script>
<style>
#test-image-preview {
width: 500px;
height: 200px;
/*border: 1px solid #ff0000;*/
}
</style>
</head>
<body>
<form>
<div id="test-file-info"></div>
<div id="test-image-preview"></div>
<input type="file" id="test-image-file" onchange="test()">
</form>
</body>
<script>
'use strict'
function test() {
let fileInput = document.getElementById('test-image-file');
let info = document.getElementById('test-file-info');
let preview = document.getElementById('test-image-preview');
fileInput.addEventListener('change', function () {
console.log('change......');
preview.style.backgroundImage='';
if (!fileInput.value) {
info.innerHTML='没有选择文件';
return;
}
let file=fileInput.files[0];
info.innerHTML='文件:' + file.name + '<br>'+'大小:'+file.size+'<br>'+'修改:'+file.lastModifiedDate;
if (file.type !== 'image/jpeg' && file.type != 'image/png' && file.type != 'image/gif') {
alert('不是有效图片');
return;
}
let reader=new FileReader();
reader.onload=function (e) {
console.log('reader.onload');
let data=e.target.result;
preview.style.backgroundImage='url('+ data +')';
}
reader.readAsDataURL(file);
});
}
</script>