JavaScript基础知识回顾:
目录:
- 比较运算符
- 多行字符串,模板字符串
- 严格模式
- 函数定义和调用
- 变量作用域与解构赋值、NameSpace、块级作用域let、const
- 方法
- 高阶函数
- 闭包
我们一个一个慢慢来:
比较运算符:
-
= 如果1=’1’,则为false
-
== 等于 类型不一样,值一样,也会判断为true
-
=== 绝对等于,类型一样,值一样,判断为true
-
!== 不等于
-
这是js的缺陷,尽量不使用==比较
浮点数问题:
console.log((1/3)===(1-2/3))
结果为false,尽管数值是都等于1/3
尽量避免使用小数计算,因为精度问题
ES6中的模版字符串:
在新行中插入的任何字符都是模板字符串中的一部分,使用普通字符串,你可以通过以下的方式获得多行字符串:
console.log('string text line 1
' +
'string text line 2');
"string text line 1
string text line 2"
要获得同样效果的多行字符串,只需使用如下代码:
console.log(`string text line 1
string text line 2`);
"string text line 1
string text line 2"
插入表达式:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var a=10;
var b = 20;
console.log(`a = ${a},b = ${b}`);
</script>
</body>
</html>
通过上述代码可知,需要把表达式${}放入到``中才能正确执行。
详细说明:MDN
严格模式:
严格模式对正常的 JavaScript语义做了一些更改。
- 严格模式通过抛出错误来消除了一些原有静默错误(undefined)。
- 严格模式修复了一些导致 JavaScript引擎难以执行优化的缺陷:有时候,相同的代码,严格模式可以比非严格模式下运行得更快。
- 严格模式禁用了在ECMAScript的未来版本中可能会定义的一些语法。
'use strict';
function getAge(){
var y = new Date().getFullYear();
return y - this.birth;
}
var xiaoming = {
name:'小明',
birth:2000,
age:getAge
};
//开不开启use strick 结果不一样
var fn = xiaoming.age;
console.log(fn());
具体链接:MDN
函数定义和调用:
定义函数方式:
定义方式一
绝对值函数
function abs(x){
return x;
}else{
return -x;
}
一旦执行到return代表函数结束,返回结果
定义方法二
var abs = function(x){
return x;
}else{
return -x;
}
function(x){}是一个匿名函数,可以把结果赋值给abs,通过abs就可以调用函数
方法一和方法二等价
调用函数:
abs(10)
abs(-10)
参数问题:javascript可以传任何个参数,也可以不传参数
参数进来是否存在的问题?假设不存在参数,如何抛出异常?
var abs = function(x){
//手动抛出异常来判断
if (typeof x !== 'number') {
throw 'not a number';
}
if (x>=o) {
return x;
}else{
return -x;
}
}
arguments对象:
加入函数的实参没有写多个,但使用时传入了多个参数,使用arguments对象可以把这多个参数用数组返回,argument对象其实就是传入的所有参数的数组。
特性:
1.arguments对象和Function是分不开的。
2.因为arguments这个对象不能显式创建。
3.arguments对象只有函数开始时才可用。
使用方法:
虽然arguments对象并不是一个数组,但是访问单个参数的方式与访问数组元素的方式相同
例如:
arguments[0],arguments[1],。。。arguments[n];
在js中 不需要明确指出参数名,就能访问它们,例如:
function test() {
var s = '';
for (var i = 0; i < arguments.length; i++) {
alert(arguments[i]);
s += arguments[i] + ',';
}
return s;
}
test("name", "age");
结果为name,age
rest参数
例如:函数定义了两个参数,但是传入了第三个参数,要怎么取出第三个参数呢?
function test(a,b){
console.log('a->'+a);
console.log('b->'+b);
//以前的方法取第三个元素:
if (arguments.length>2) {
for(var i = 2; i<arguments.length;i++){
console.log(arguments[i])
}
}
}
//现在的方法(rest参数):在函数中定义rest参数
function test1(a,b,...rest){
console.log('a->'+a);
console.log('b->'+b);
console.log(rest);
}
变量的作用域:
变量的作用域:
function a(){
var x = 1;
//内部函数可以访问外部函数的成员,反之不行
function aa(){
var y = x +1; //2
}
//外部访问了内部函数的变量,会不行
var z = y+1; //报错
}
function foo(a,b){
var x = 1;
function bar(){
var x = 'A';
console.log(x);
}
console.log(x);
bar();
}
foo();
结果: 1 A
全局对象window
'use strict';
window.alert('调用Windows.alert');
var old_alert = window.alert;
window.alert = function(){
alert('无法使用alert方法');
}
window.alert = old_alert;
alert('又可以使用alert方法了');
调用的结果:只执行了两次,第一次输出-->调用Windows.alert;第二次输出-->又可以使用alert方法了
Let关键字:
局部作用域let
ES6let关键字,解决局部作用域冲突问题,现建议大家都用let去定义局部变量
function aaa() {
for(vari=0;i<100;i++){
console.log(i)
}
console.log(i+1); //问题? i 出了这个作用域还可以使用
}
//使用let后
function aaa() {
for(leti=0;i<100;i++){
console.log(i)
}
console.log(i+1); //Uncaught ReferenceError: i is not defined
}
const关键字:
在ES6之后,用const定义常量;
const PI = '3.14';
console.log(PI);
PI = '123'; //报错,常量不允许修改
命名空间NameSpace:
防止重名以及命名污染的现象发生;
var MYAPP = {};
var MYAPP2 = {};
MYAPP.name = 'myapp';
MYAPP.version = '1.0';
MYAPP.foo = function(){
console.log("测试");
};
MYAPP.foo();
MYAPP2.name = 'myapp';
MYAPP2.version = '1.0';
MYAPP2.foo = function(){
console.log("测试2");
};
MYAPP2.foo();
方法:
定义方法
方法就是把函数放在对象的里面,对象只有两个东西:属性和方法
var xiaoming = {
name:'小明',
birth:2000,
age:function(){
var y = new Date().getFullYear();
return y -this.birth;
}
};
console.log(xiaoming.age());
成员属性只对子方法负责,不对孙方法负责。
var xiaoming = {
name:'小明',
birth:2000,
age:function (){
//保存xiaoming这个对象
var that = this;
function getAgeFromBirth(){
var y = new Date().getFullYear();
//如果不保存,这里是找不到birth属性的
return y - that.birth;
}
return getAgeFromBirth();
}
}
console.log(xiaoming.age());
为了解决上面这个缺陷:我们引入了apply关键字;
apply方法是可以控制this指向的,该方法有两个参数,第一个是getArg要使用的是那个对象,第二个是数组;
//解决的js的缺陷
function getAge(){
var y = new Date().getFullYear();
return y - this.birth;
}
var xiaoming = {
name:'小明',
birth:2000,
age :getAge
};
//apply(x,y);
//第一个参数是getAge中this的所需要的指向(不指向为null)
//第二个参数默认是数组格式,表示传入的参数类型
console.log(getAge.apply(xiaoming,[]));
高阶函数使用:
map、reduce、filter
map:实现每个数平方
function pow(x){
return x * x;
}
var arr = [1,2,3,4,5,6,7,8,9];
var result = arr.map(pow);
console.log('='+result);
reduce:实现累加
var arr = [1,2,3,4,5];
//1+2-->3 x
//x+4-->7 x
//x+5-->12 x
var result = arr.reduce(function(x,y){
return x+y;
});
console.log(result);
filter:过滤掉不符合函数要求的值
var arr = [1,2,3,4,5,6,7];
var r = arr.filter(function(x){
return x%2 !== 0;
});
console.log(r);
闭包:
闭包的引入:
//函数内部可以访问全局变量
var n = 999;
function f1(){
console.log(n);
}
//外部访问不了函数内部的变量
function f1(){
var n = 999;
}
console.log(n);
使用闭包来实现外部引用内部信息:
function f1(){
var n = 999;
function f2(){
console.log(n);
}
return f2;
}
var res = f1();
res();
复杂闭包的实现:
//闭包复杂代码段
function createIncermentor(start){
return function(){
return start++;
};
}
var inc = createIncermentor(10);
console.log(inc());
console.log(inc());
console.log(inc());
结果:10 11 12
定义类:
function Person(){
var _age;
function setAge(n){
_age = n;
}
function getAge(){
return _age;
}
//{} //var obj = {}是对象
return {
name:name,
getAge:getAge,
setAge:setAge
};
}
var p1 = Person("xbhog");
p1.setAge(88);
console.log(p1.getAge());
结果:88
感觉可以的朋友,可以给我点点关注或者推荐,感谢!