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