1、变量提升
提升声明,不提升赋值
2、所有的全局变量和函数都是绑定在window对象上的属性
3、命名空间
是为了解决全局变量冲突的问题
4、var定义的变量,在for循环等语句块中没有局部作用域,for循环外边可以输出变量;let定义的变量,有块级作用域,只在作用域内有效;const 定义一个常量,只读;
5、解构·赋值
var person = {
name: '小明',
age: 20,
gender: 'male',
passport: 'G-12345678',
school: 'No.4 middle school'
};
// 将passport值赋给id
let {name, passport:id} = person;
console.log(id); // 'G-12345678'
6、高阶函数
(1)arr.map(function) // 把f(x)作用在Array的每一个元素并把结果生成一个新的Array
(2)arr.reduce(function) // reduce()把结果继续和序列的下一个元素做累积计算
练习:不要使用JavaScript内置的parseInt()函数,利用map和reduce操作实现一个string2int()函数
'use strict';
function string2int(s) {
function str2num(str) {
var strArr = str.split("");
function toInt(data) {
return +data;
}
return strArr.map(toInt);
}
var num = str2num(s);
var res = num.reduce(function(x,y){
return x*10+y;
});
return res;
}
// 测试:
if (string2int('0') === 0 && string2int('12345') === 12345 && string2int('12300') === 12300) {
if (string2int.toString().indexOf('parseInt') !== -1) {
console.log('请勿使用parseInt()!');
} else if (string2int.toString().indexOf('Number') !== -1) {
console.log('请勿使用Number()!');
} else {
console.log('测试通过!');
}
}
else {
console.log('测试失败!');
}
练习:请把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:['adam', 'LISA', 'barT'],输出:['Adam', 'Lisa', 'Bart']。
'use strict';
function normalize(arr) {
var result = arr.map(function(x) {
var first = x.slice(0,1).toUpperCase();
var lower = x.slice(1).toLowerCase();
return first+lower;
})
return result;
}
// 测试:
if (normalize(['adam', 'LISA', 'barT']).toString() === ['Adam', 'Lisa', 'Bart'].toString()) {
console.log('测试通过!');
}else {
console.log('测试失败!');
}
(3)arr.filter(function) 回调函数作用于arr的每个元素,根据返回值是false还是true决定保留还是过滤掉。回调函数可以节后三个参数(数组的每一个元素,index, arr本身)
练习:请尝试用filter()筛选出素数
'use strict';
function get_primes(arr) {
function isPrimeNumber(x) {
if(x===1) {
return false;//1不是素数,返回false
}
//i是2到x开平方根之间的整数
//如果x对i取余等于0,则不是素数,返回false
for(let i=2;i<=Math.sqrt(x,2);i++) {
if(x%i===0) {
return false;
}
}
//如果上述条件都不满足,则是素数,返回true
return true;
}
//用filter()返回新的只含有素数的数组
return arr.filter(isPrimeNumber);
}
// 测试:
var
x,
r,
arr = [];
for (x = 1; x < 100; x++) {
arr.push(x);
}
r = get_primes(arr);
if (r.toString() === [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97].toString()) {
console.log('测试通过!');
} else {
console.log('测试失败: ' + r.toString());
}
(4)arr.sort()方法法默认把所有元素先转换为String再排序,会直接对Array进行修改
(5)every()方法可以判断数组的所有元素是否满足测试条件。
(6)find()方法用于查找符合条件的第一个元素,如果找到了,返回这个元素,否则,返回undefined:
(7)findIndex()和find()类似,也是查找符合条件的第一个元素,不同之处在于findIndex()会返回这个元素的索引,如果没有找到,返回-1:
(8)forEach()和map()类似,它也把每个元素依次作用于传入的函数,但不会返回新的数组。forEach()常用于遍历数组,因此,传入的函数不需要返回值;
7、箭头函数
如果函数表达式只有一句可以省略{......}和return;如果多个语句不能省略;
8、面向对象编程
(1)在JS中没有class类的概念,所有的对象都是实例,继承关系就是一个对象的原型指向另一个对象。
(2)创建对象 Object.create()
(3)原型对象才有prototype(原型)属性,新创建的对象没有。
JavaScript的原型继承实现方式就是:
- 定义新的构造函数,并在内部用call()调用希望“继承”的构造函数,并绑定this;
- 借助中间函数F实现原型链继承,最好通过封装的inherits函数完成;
- 继续在新的构造函数的原型上定义新方法。