js使用方式
- js可以直接嵌套到html中执行
- 外部引入js文件
js语法
JavaScript的语法和Java语言类似,每个语句以`;`结束,语句块用`{...}`。但是,JavaScript并不强制要求在每个语句的结尾加`;`,浏览器中负责执行JavaScript代码的引擎会自动在每个语句的结尾补上`;`
注释
单行注释//
多行注释/**/
数据类型和变量
Number 数值类型
String 字符串
Boole 布尔类型 true false
NaN 空类型属于数值
null 空
undefined 未定义
Array 数组
Object 对象
变量声明和赋值
/*声明变量*/
var x=1; /*声明并且赋值*/
var x; /*声明*/
x=111; /*赋值*/
/*js不强制用var声明,使用强制模式必须使用开启强制模式就是在js的开头使用use strict*/
js的输出方式
alert('111') /*直接弹出*/
console.log(111) /*控制台输出*/
document.write(111)/*直接输出在网页上*/
js拼接用+号
var a="张三";
var b=111;
var c=a+b;
document.write(c);
/*输出张三111*/
js数组Array
/**
* 计算数组的长度输出 length
* 获取数组的值 arr[2]
* 修改数组的值 arr[2]=111
* 搜索数组中指定的值索引indexOf
* 截取数组中元素slice(0,3)参数1开始位置参数2结束位置一个参数则为截取的开始位置
* push pop
* 头部添加若干元素,使用unshift()方法,shift()方法则把Array的第一个元素删掉
* push返回Array新的长度: 7向数组的末尾添加元素pop删除末尾的元素,返回删除的元素
* reverse()翻转数组
* splice()方法是修改Array的“万能方法”,它可以从指定的索引开始删除若干元素,然后再从该位置添加若干元素:
* arr.splice(2, 3, 'Google', 'Facebook');删除并添加
* arr.splice(2, 2);删除不添加
* arr.splice(2, 0, 'Google', 'Facebook');添加不删除
* concat()方法把当前的Array和另一个Array连接起来,并返回一个新的Array
* join()方法是一个非常实用的方法,它把当前Array的每个元素都用指定的字符串连接起来,然后返回连接后的字符串
*/
var arr=[1,'aaa',3.13,'null',true];
arr.length;
arr[2];
arr[2]=11111;
arr.indexOf(1);
arr.slice(0, 3);
arr.slice(3);
arr.push('A', 'B');
arr.pop();
arr.unshift('1',2);
arr.shift();
arr.reverse();
arr.splice(2, 3, 'Google', 'Facebook');
arr.splice(2, 2);
arr.splice(2, 0, 'Google', 'Facebook');
arr.concat([1,2,3]);
var arr = ['A', 'B', 'C', 1, 2, 3];
arr.join('-'); // 'A-B-C-1-2-3'
对象Object:JavaScript的对象是一种无序的集合数据类型,它由若干键值对组成。
1.定义方式:var object={key:value}
2.例如:var zhangsan={name:'张三',sex:'男'}
3.访问方式zhangsan.name
4.访问不存在的对象属性返回 undefined
5.添加一个对象属性zhangsan.age=25
6.删除一个对象属性delete.zhangsan.age
7.检测属性是否存在 'name' in xiaoming 存在为true否则为false
8.要判断一个属性是否是`xiaoming`自身拥有的,而不是继承得到的,可以用`hasOwnProperty()`方法,xiaoming对象继承了父类的对象属性也属于xiaoming
条件判断
if(a>2){
alert(2)
}else{
alert(1)
}
循环
/*for循环*/
for (i=1; i<=10000; i++) {
x = x + i;
}
/*利用索引遍历数组*/
var arr = ['Apple', 'Google', 'Microsoft'];
var i, x;
for (i=0; i<arr.length; i++) {
x = arr[i];
console.log(x);
}
/*for in 循环*/
var o = {
name: 'Jack',
age: 20,
city: 'Beijing'
};
for (var key in o) {
console.log(key); // 'name', 'age', 'city'
}
/*while循环*/
var x = 0;
var n = 99;
while (n > 0) {
x = x + n;
n = n - 2;
}
/*do while循环*/
var n = 0;
do {
n = n + 1;
} while (n < 100);
判断浏览器是否支持Map和Set
判断浏览器是否支持Map和Set
'use strict';
var m = new Map();
var s = new Set();
console.log('你的浏览器支持Map和Set!');
报ReferenceError错误不支持
Map实例
var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.get('Michael'); // 95
var m = new Map(); // 空Map
m.set('Adam', 67); // 添加新的key-value
m.set('Bob', 59);
m.has('Adam'); // 是否存在key 'Adam': true
m.get('Adam'); // 67
m.delete('Adam'); // 删除key 'Adam'
m.get('Adam'); // undefined
一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉~~~~
var m = new Map();
m.set('Adam', 67);
m.set('Adam', 88);
m.get('Adam'); // 88
Set实例
var s1 = new Set(); // 空Set
var s2 = new Set([1, 2, 3]); // 含1, 2, 3
var s = new Set([1, 2, 3, 3, '3']);
s; // Set {1, 2, 3, "3"}重复元素自动被过滤
//添加元素
s.add(4);
s; // Set {1, 2, 3, 4}
s.add(4);
s; // 仍然是 Set {1, 2, 3, 4}重复添加被过滤
//删除元素
var s = new Set([1, 2, 3]);
s; // Set {1, 2, 3}
s.delete(3);
s; // Set {1, 2}
iterable ES6新类型数组、Map、Set都属于这一类型
for...of循环遍历集合
var a = ['A', 'B', 'C'];
var s = new Set(['A', 'B', 'C']);
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
for (var x of a) { // 遍历Array
console.log(x);
}
for (var x of s) { // 遍历Set
console.log(x);
}
for (var x of m) { // 遍历Map
console.log(x[0] + '=' + x[1]);
}
for...of循环和for...in循环的区别
var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x in a) {
console.log(x); // '0', '1', '2', 'name'
}
var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x of a) {
console.log(x); // 'A', 'B', 'C'
}
不同点:
for ... in`循环将把`name`包括在内,但`Array`的`length`属性却不包括在内。
for ... of`循环则完全修复了这些问题,它只循环集合本身的元素:
JS函数
定义函数
/*第一种方式*/
function abs(x) {
if (x >= 0) {
return x;
} else {
return -x;
}
}
/*第二种方式*/
var abs = function (x) {
if (x >= 0) {
return x;
} else {
return -x;
}
};
document.write(abs(1));
arguments它只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数。arguments
类似Array
但它不是一个Array
,arguments
,你可以获得调用者传入的所有参数。也就是说,即使函数不定义任何参数,还是可以拿到参数的值
/*arguments*/
function foo(x) {
document.write('x = ' + x); // 10
for (var i=0; i<arguments.length; i++) {
document.write('arg ' + i + ' = ' + arguments[i]); // 10, 20
}
}
foo(10, 20);
rest参数只能写在最后,前面用...
标识,从运行结果可知,传入的参数先绑定a
、b
,多余的参数以数组形式交给变量rest
function foo(a, b, ...rest) {
console.log('a = ' + a);
console.log('b = ' + b);
console.log(rest);
}
foo(1, 2, 3, 4, 5);
// 结果:
// a = 1
// b = 2
// Array [ 3, 4, 5 ]
foo(1);
// 结果:
// a = 1
// b = undefined
// Array []
变量作用域、常量1.
var申明的变量实际上是有作用域的。如果一个变量在函数体内部申明,则该变量的作用域为整个函数体,在函数体外不可引用该变量:
2.不同函数内部的同名变量互相独立,互不影响
3.由于JS的函数可以嵌套,此时,内部函数可以访问外部函数定义的变量,反过来则不行
4.JavaScript的函数在查找变量时从自身函数定义开始,从'内'向'外'查找
5.let,用let替代var可以申明一个块级作用域的变量:
6.声明常量 ES6 const PI = 3.14;
解析赋值
/*传统写法*/
var array = ['hello', 'JavaScript', 'ES6'];
var x = array[0];
var y = array[1];
/*ES6写法*/
var [x, y, z] = ['hello', 'JavaScript', 'ES6'];
let [x, [y, z]] = ['hello', ['JavaScript', 'ES6']];
/*忽略元素*/
let [, , z] = ['hello', 'JavaScript', 'ES6'];
/*对象中取出若干属性*/
var person = {
name: '小明',
age: 20,
gender: 'male',
passport: 'G-12345678',
school: 'No.4 middle school'
};
var {name, age, passport} = person;
/*嵌套对象进行操作*/
var person = {
name: '小明',
age: 20,
gender: 'male',
passport: 'G-12345678',
school: 'No.4 middle school',
address: {
city: 'Beijing',
street: 'No.1 Road',
zipcode: '100001'
}
};
var {name, address: {city, zip}} = person;
方法:在一个对象中绑定函数,称为这个对象的方法
var xiaoming = {
name: '小明',
birth: 1990,
age: function () {
var y = new Date().getFullYear();
return y - this.birth;
}
};
xiaoming.age; // function xiaoming.age()
xiaoming.age(); // 今年调用是25,明年调用就变成26了
this是一个特殊变量,它始终指向当前对象,也就是xiaoming这个变量
var xiaoming = {
name: '小明',
birth: 1990,
age: function () {
var y = new Date().getFullYear();
return y - this.birth;
}
};
xiaoming.age; // function xiaoming.age()
xiaoming.age(); // 今年调用是25,明年调用就变成26了
this指向全局window
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
var xiaoming = {
name: '小明',
birth: 1990,
age: getAge
};
xiaoming.age(); // 25, 正常结果
getAge(); // NaN
要指定函数的this指向哪个对象,可以用函数本身的apply方法,它接收两个参数,第一个参数就是需要绑定的this变量,第二个参数是Array,表示函数本身的参数,用apply修复getAge()调用:
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
var xiaoming = {
name: '小明',
birth: 1990,
age: getAge
};
xiaoming.age(); // 25
getAge.apply(xiaoming, []); // 25, this指向xiaoming, 参数为空
apply()把参数打包成Array再传入;
call()把参数按顺序传入。
Math.max.apply(null, [3, 5, 4]); // 5
Math.max.call(null, 3, 5, 4); // 5
JS高阶函数map/reduce
把一个函数作用在数组上
map
function pow(x) {
return x * x;
}
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var results = arr.map(pow); // [1, 4, 9, 16, 25, 36, 49, 64, 81]
console.log(results);
reduce()把结果继续和序列的下一个元素做累积计算,其效果就是:
var arr = [1, 3, 5, 7, 9];
arr.reduce(function (x, y) {
return x + y;
}); // 25
filter也是一个常用的操作,它用于把Array的某些元素过滤掉,然后返回剩下的元素。和map()类似,Array的filter()也接收一个函数。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素
var arr = [1, 2, 4, 5, 6, 9, 10, 15];
var r = arr.filter(function (x) {
return x % 2 !== 0;
});
r; // [1, 5, 9, 15]
排序算法
sort排序的误区
['Google', 'Apple', 'Microsoft'].sort(); // ['Apple', 'Google', 'Microsoft'];
// apple排在了最后:
['Google', 'apple', 'Microsoft'].sort(); // ['Google', 'Microsoft", 'apple']
// 无法理解的结果:
[10, 20, 1, 2].sort(); // [1, 10, 2, 20]
/*
第二个排序把`apple`排在了最后,是因为字符串根据ASCII码进行排序,而小写字母`a`的ASCII码在大写字母之后。
这是因为`Array`的`sort()`方法默认把所有元素先转换为String再排序,结果`'10'`排在了`'2'`的前面,因为字符`'1'`比字符`'2'`的ASCII码小。
*/
map其他函数
1.every()
方法可以判断数组的所有元素是否满足测试条件。
2.find()
方法用于查找符合条件的第一个元素,如果找到了,返回这个元素,否则,返回undefined
3.findIndex()
和find()
类似,也是查找符合条件的第一个元素,不同之处在于findIndex()
会返回这个元素的索引,如果没有找到,返回-1
:
4.forEach()
和map()
类似,它也把每个元素依次作用于传入的函数,但不会返回新的数组。forEach()
常用于遍历数组,因此,传入的函数不需要返回值:
闭包
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。