JavaScript基础以及进阶知识

JavaScript基础知识回顾:

目录:

  1. 比较运算符
  2. 多行字符串,模板字符串
  3. 严格模式
  4. 函数定义和调用
  5. 变量作用域与解构赋值、NameSpace、块级作用域let、const
  6. 方法
  7. 高阶函数
  8. 闭包

我们一个一个慢慢来:

比较运算符:

  • = 如果1=’1’,则为false

  • == 等于 类型不一样,值一样,也会判断为true

  • === 绝对等于,类型一样,值一样,判断为true

  • !== 不等于

  • 这是js的缺陷,尽量不使用==比较

    浮点数问题:
    console.log((1/3)===(1-2/3))
    结果为false,尽管数值是都等于1/3
    尽量避免使用小数计算,因为精度问题

ES6中的模版字符串:

在新行中插入的任何字符都是模板字符串中的一部分,使用普通字符串,你可以通过以下的方式获得多行字符串:

console.log('string text line 1\n' +
'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语义做了一些更改。

  1. 严格模式通过抛出错误来消除了一些原有静默错误(undefined)
  2. 严格模式修复了一些导致 JavaScript引擎难以执行优化的缺陷:有时候,相同的代码,严格模式可以比非严格模式下运行得更快
  3. 严格模式禁用了在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
感觉可以的朋友,可以给我点点关注或者推荐,感谢!

参考引自:

JavaScript | MDN

狂神说JavaScript