js基礎知識

js複習

js知識點介紹

基礎知識

一、原型、原型鏈

二、做用域、閉包

三、異步單線程

jsAPI

一、DOM操做

二、AJax

三、事件綁定

開發環境

一、版本管理

二、模塊化

三、打包工具

運行環境

一、頁面渲染

二、性能優化

1、原型和原型鏈

一、構造函數

<script>
    function Foo(name,age){
        this.name = name;
        this.age = age;
        this.class = 'class-1';
        // return this; 默認有這一行
    }
    var f = new Foo('zhangsan',20);
    var f1 =new Foo('lisi',22); //建立多個對象
</script>

二、構造函數--擴展

  • var a = {}實際上是var a = new Object()的語法糖
  • var a = []實際上是var a = new Array()的語法糖
  • function Foo(){...}實際上是var Foo = new Function(...)的語法糖
  • 使用instanceof判斷一個函數是不是一個變量的構造函數
  • 判斷一個變量是否爲「數組」
  • 變量 instanceof Array

三、原型規則和示例

5條原型規則

  • 原型規則是學習原型鏈的基礎
  • 一、全部的引用類型(數組、對象、函數)都具備對象特性,即自由擴展特性(除了"null"之外)javascript

    var obj = {};
      obj.a = 100;
      var arr = [];
      arr.a = 100;
      function fn(){};
      fn.a = 100;
  • 二、全部的引用類型(數組、對象、函數),都有一個__proto__屬性,屬性值是一個普通對象html

    console.log(obj.__proto__);
      console.log(arr.__proto__);
      console.log(fn.__proto__);
  • 三、全部的函數,都有一個prototype屬性,屬性值也是一個普通對象。前端

    console.log(fn.prototype)
  • 四、全部的引用類型(數組、對象、函數),__proto__屬性值指向它的構造函數的prototype屬性值
  • __proto__隱式類型原型
  • prototype顯示類型原型java

    console.log(obj.__proto__ === Object.prototype)//true
  • 五、當試圖獲得一個對象的某個屬性時,若是這個對象自己沒有這個屬性,那麼會去它的__proto__(即它的構造函數的prototype)中尋找。ajax

    //構造函數
      function Foo(name,age){
          this.name = name;
      }
      Foo.prototype.alertName = function(){
          alert(this.name);
      }
      //建立實例
      var f = new Foo('zhangsan');
      f.printName = function(){
          console.log(this.name);
      }
      //測試
      f.printName();//zhangsan
      f.alertName(); //zhangsan

循環對象自身的屬性 hasOwnProperty

var item;
for(item in f){
    //高級瀏覽器已經在for in 屏蔽了來自原型的屬性
    if(f.hasOwnProperty(item)){
        console.log(item);//name  printName
    }
}

四、原型鏈

五、instanceof

  • f instanceof Foo的判斷邏輯是
  • f的__proto__一層一層往上,可否對應到Foo.prototype再試着判斷f instanceof Object

問題

一、如何準確的判斷一個變量是數組類型

var arr=[];
arr instanceof Array; //true
typeof arr;  //Object,typeof是沒法判斷是不是數組的

二、寫一個原型鏈繼承的例子

//動物
function Animal() {
    this.eat = function(){
        console.log('animal eat');
    }
}
//狗
function Dog(){
    this.bark = function(){
        console.log('dog bark');
    }
}
Dog.prototype = new Animal();
var hashiqi = new Dog();//哈士奇

三、描述new 一個對象的過程

  • 建立一個新對象
  • this指向這個新對象
  • 執行代碼即對this賦值
  • 返回thisjson

    //構造函數
      function Foo(name,age){
          this.name = name;
          this.age = age;
          this.class = 'class-1';
      }
      var f = new Foo('zhangsan',20)

四、寫一個dom查詢的例子

function Elem(id){
        this.elem = document.getElementById(id);
    }
    Elem.prototype.html = function(val){
        var elem = this.elem;
        if(val){
            elem.innerHTML = val;
            return this;//鏈式操做
        }else {
            return elem.innerHTML;
        }
    }
    Elem.prototype.on = function(type,fn){
        var elem = this.elem;
        elem.addEventListener(type,fn);
        return this;
    }
    var div1 = new Elem('div1');
    div.html('<p>hello world').on('click',function(){
        alert('clicked')
    }).html('<p>javascript</p>')

2、做用域、閉包

一、執行上下文

  • 一、範圍:一段<script>或者一個函數
  • 二、全局:變量定義、函數聲明一段<script>
  • 三、函數:變量定義、函數聲明、this.argument函數
  • ps:注意函數聲明和函數表達式的區別api

    console.log(a);//undefined
      var a = 100;//函數聲明
      fn('zhangsan'); //'zhangshan' 20
      function fn(name){//函數表達式
          age = 20;
          console.log(name,age)
          var age;
      }

二、this

  • this要在執行時才能肯定值,定義時沒法肯定數組

    var a = {
          name: 'A',
          fn:function(){
              console.log(this.name);
          }
      }
      a.fn();//this === a
      a.fn.call({name:'B'});//this === {name:'B'}
      var fn1 = a.fn;
      fn1(); //this === window;
  • (1)、做爲構造函數執行瀏覽器

    Function Foo(name){
          this.name = name;
      }
      var f = new Foo('zhangsan')
  • (2)、做爲對象屬性執行性能優化

    var obj = {
          name: 'A',
          printName:function(){
              console.log(this.name)
          }
      }
      obj.printName();
  • (3)、做爲普通函數執行

    function fn(){
          console.log(this)
      }
      fn();
  • (4)、call\apply\bind

    function fn1(name,age){
          alert(name);
          console.log(this);
      }
      fn1.call({x:100},'zhangsan',20)
      fn1.apply({x:100},['zhangsan',20])
      var f2 = function (name,age){
          alert(name);
          console.log(this);
      }.bind({y:200});
      fn2('zhangsan',20)

三、做用域

  • 一、沒有塊級做用域
  • 二、只有函數和全局做用域

    //無塊級做用域
      if(true){
          var name = 'zhangsan';
      }
      console.log(name);//zhangsan
    
    
      //函數和全局做用域
      var a = 100;
      function fn(){
          var a = 200;
          console.log('fn',a)//fn 200
      }
      console.log('global',a)//global 100
      fn();

四、做用域鏈

var a = 100;
function fn(){
    var b = 200;
    //當前做用域沒有定義的變量,即自由變量
    console.log(a)//100
    console.log(b)//200
}
fn()

五、閉包

function F1(){
    var a = 100;
    //返回一個函數(函數做爲返回值)
    return function(){
        console.log(a)//100自由變量父做用域尋找
    }
}
//獲得一個函數
var f1 = F1();
var a = 200;
f1();

六、閉包的使用場景

  • 一、函數做爲返回值
  • 二、函數做爲參數傳遞

    function F1(){
          var a = 100;
          return function(){
              console.log(a)
          }
      }
      var f1 = F1();
      function F2(fn){
          var a = 200;
          fn();
      }
      F2(f1);//100

問題

一、說一下變量提高的理解

  • 變量升級 變量是在存儲信息的容器
  • 函數聲明(注意和函數表達式的區別)
  • 變量提高就是,在變量的做用域內,無論變量在何處聲明,都會提高到做用域的頂部,可是變量初始化的順序不變。

    function test(){
          a = 1;
          b = 2;
          var a b;
          console.log(a)
          console.log(b)
      }

二、說明this幾種不一樣的場景

  • 一、構造函數執行
  • 二、做爲對象屬性執行
  • 三、做爲普通函數執行
  • 四、call、apply、bind

三、如何理解做用鏈

  • 自由變量
  • 做用域鏈,即自由變量的查找
  • 閉包的兩個場景

實際開發中閉包的應用

//閉包實際應用中主要封裝變量,收斂權限
function isFirstLoad(){
    var _list = [];
    return function(id){
        if(_list.indexOf(id)>=0){
            return false;
        }else {
            _list.push(id);
            return true;
        }
    }
}
//使用
var firstLoad = isFirstLoad();
firstLoad(0);//true
firstLoad(10);//false
firstLoad(20);//true
//你在isFirstLoad函數外面,根本不可能修改掉_list的值

3、異步和單線程

  • 什麼是異步(對比異步)
  • 前端使用用異步的場景
  • 異步和單線程

一、什麼是異步

console.log(100);
setTimeout(function(){
    console.log(200)
},1000);
console.log(300);
//100 300 200順序
//對比同步 同步會有阻塞
console.log(100);
alert(200);//幾秒中以後單擊確認
console.log(300);
//100 200 300

二、什麼時候須要異步

  • 在可能發生等待的狀況
  • 等待過程不能像alert同樣阻塞程序運行,所以,因此的「等待的狀況」都須要異步。

三、前端使用異步的場景

  • 一、定時任務:setTimeout、setInverval
  • 二、網絡請求:ajax請求、動態加載
  • 三、事件綁定

  • ajax請求代碼示例

    console.log('start')
      $.get('/data.json',function(data1){
          console.log(data1);
      }
      console.log('end');//start end data1
  • 加載示例

    cosnole.log('start');
      var img = document.createElement('img');
      img.onload = function(){
          console.log('loaded')
      }
      img.src = '/xxx.png';
      console.log('end');//start end loaded
  • 事件綁定示例

    cosnole.log('start');
      document.getElementById('btn1').addEventListener('click',function(){
          alert('clicked');
      })
      console.log('end');
      //start end clicked

四、異步和單線程

console.log(100);
    setTimeout(function(){
        console.log(200);
    })
    console.log(300);
    //100 300 200
  • 1.執行第一行,打印100。
  • 2.執行setTimeout後傳入setTimeout的函數會被暫存起來,不會當即執行(單線程的特色,不能同時幹兩件事)。
  • 3.執行最後一行打印300。
  • 4.待全部程序執行完,處於空閒狀態時,會立馬看有沒有暫存起來的要執行。
  • 5.發現暫存起來的setTimeout中的函數無需等待時間,就當即來過來執行。

問題

一、同步和異步區別是什麼

  • 1.同步會阻塞代碼執行,而異步不會
  • 2.alert是同步,setTimeout是異步

二、一個關於setTimeout的筆試題

console.log(1);
setTimeout(function(){
    console.log(2);
},0)
console.log(3);
setTimeout(function(){
    console.log(4)
},1000)
console.log(5);
//1 3 5 2 4

三、前端使用異步的場景有哪些

  • 定時任務:setTimeout、setInverval
  • 網絡請求:ajax請求、動態加載
  • 事件綁定

4、其餘知識

知識點

  • 日期、Math、數組API、對象API

一、日期

  • Date.now() //獲取當前時間的毫秒數
  • var dt = new Date();
  • dt.getTime(); //獲取毫秒數
  • dt.getFullYear(); //年
  • dt.getMonth();//月(0-11)
  • dt.getDate(); //日(0-31)
  • dt.getHours();//小時(0-23)
  • dt.getMinutes();//分鐘(0-59)
  • dt.getSeconds();//秒(0-59)

二、Math

  • 獲取隨機數Math.random()

三、數組API

  • forEach 遍歷全部元素
  • every 判斷全部元素是否都符合條件
  • some 判斷是否有至少一個元素符合條件
  • sort 排序
  • map 對元素從新組裝,生成新數組
  • filter 過濾符合條件的元素

  • forEach

    var arr = [1,2,3]
      arr.forEach(function(item,index){
          //遍歷數組的全部元素
          console.log(index,item)
      })
  • every

    var arr = [1,2,3];
      var result = arr.every(function(item,index){
          //用來判斷全部的數組元素,都知足一個條件
          if(item<4){
              return ture
          }
      })
      console.log(result)//true
  • some

    var arr = [1,2,3];
      var result = arr.some(function(item,index){
          //用來判斷全部的數組元素,只要有一個知足條件便可
          if(item<2){
              return true
          }
      })
      console.log(result)//true
  • sort

    var arr = [1,4,2,3,5];
      var arr2 = arr.sort(function(a,b){
          //從小到大排序
          return a-b
          //從大到小的排序
          return b-a
      })
      console.log(arr2);
  • map

    var arr = [1,2,3,4];
      var arr2 = arr.map(function(item,index){
          //將元素從新組裝,並返回
          return '<br>'+item+'</b>'
      })
      console.log(arr2)
  • filter

    var arr = [1,2,3];
      var arr2 = arr.filter(function(item,index){
          //經過某一個條件過濾數組
          if(item>=2){
              return true
          }
      })
      console.log(arr2);//2 3

四、對象API for in

var obj = {x:100,y:200,z:300};
var key;
for(key in obj){
    if(obj.hasOwnProperty(key)){
        console.log(key,obj[key])
    }
}
//x, 100;y ,200;z,300

解題

一、獲取2019-02-16(當前時間)

function formatDate(dt) {
        if(!dt){
            dt = new Date();
        }
        var year = dt.getFullYear();
        var month = dt.getMonth()+1;
        var date = dt.getDate();
        if(month < 10){
            //強制類型轉換
            month = '0'+month;
        }
        if(date <10){
            //強制類型轉換
            date = '0'+date;
        }
        //強制類型轉換
        return year + '-'+month + '-'+date;
    }
    var dt = new Date();
    var formatDate = formatDate(dt);
    console.log(formatDate);//2019-02-16

二、獲取隨機數,要求是長度一致的字符串格式

var random = Math.random();
random = random + '0000000000'//後面加上10個0
random = random .slice(0,10);
console.log(random)

三、寫一個能遍歷對象和數組的forEach函數

function forEach(obj,fn){
    var key;
    if(obj instanceof Array){
        //準確判斷是不是數組
        obj.forEach(function(item,index){
            fn(index,item);
        })
    }else {
        //不是數組就是對象
        for(key in obj){
            if(obj.hasOwnProperty(key)){
                fn(key,obj[key])
            }
        }
    }
}
var arr = ['蘋果','香蕉','梨'];
//注意,這裏的參數的順序換了,爲了和對象的遍歷格式一致
forEach(arr,function(index,item){
    console.log(index,item)
    // 0 "蘋果"
    // 1 "香蕉"
    // 2 "梨"
})
var obj = {x:100,y:200};
forEach(obj,function(key,value){
    console.log(key,value)
    // x 100
    // y 200
})
相關文章
相關標籤/搜索