JS基礎難點總結(函數做用域,變量提高,對象,構造函數,this)全!!!

JavaScript的組成

ECMAScrpit - 描述了語言的基本語法和數據類型  
BOM - 瀏覽器對象模型:一套操做瀏覽器功能的API,能夠經過BOM彈框,獲取屏幕分辨率  
DOM - 文檔對象模型:一套操做頁面元素的API,能夠操做文檔樹上的節點
複製代碼

變量

什麼是變量

變量是計算機內存中存儲數據的標識符,根據變量名能夠獲取內存中存儲的數據   
使用變量能夠方便的獲取或修改內存中的數據
複製代碼

如何使用變量

用var來聲明
var a = 'monster'
注意:js中的變量若是不用var來聲明,如: b = 'monster' ,b就是全局變量(全局對象屬性)javascript

var a = b = 'monster'
在預編譯時會被解析爲 
var a;
a = 'monster';
b = 'monster'
複製代碼

這時b就是一個全局變量,可是不推薦使用java

函數

實參和形參

// 函數內部是一個封閉的環境,能夠經過參數的方式,把外部的值傳遞給函數內部
// 帶參數的函數聲明
function 函數名(形參1, 形參2, 形參3...) {
  // 函數體
}
// 帶參數的函數調用
函數名(實參1, 實參2, 實參3); 
形參1 = 實參1
形參2 = 實參2
複製代碼
var x = 5, y = 6;
fn(x,y); 
function fn(a, b) {
  console.log(a + b);
}
//x,y是實參,函數執行的時候會把x,y複製給a,b;函數內部是複製後的新值,沒法改變外部的x,y
複製代碼

函數的返回值

1.//聲明一個帶返回值的函數
function 函數名(形參1, 形參2, 形參3...) {
  //函數體
  return 返回值;
}
2.//用變量接受這個返回值
var 變量 = 函數名(形參1, 形參2, 形參3...)
函數的調用結果就是返回值,所以咱們能夠直接對函數調用結果進行操做。
複製代碼

arguments

函數內部 arguments 對象:能夠經過arguments獲取函數的實參。 例:能夠用來求 任意數字的和數組

1. 能夠經過arguments獲取函數調用時傳入的實參
function test(a,b,c) {
    console.log(arguments)
}
2. 求任意個數的最大值
function getMax() {
    max = arguments[0];
    for(var i = 0; i < arguments.length; i++) {
        if(max < arguments[i]) {
            max = arguments[i];
        }
    }
    return max;
}

var max = getMax(2,10,4,67,29)   //傳入不定個數的數組
console.log(max)
複製代碼

函數是一種數據類型

function fn() {}
console.log(typeof fn);
複製代碼
  • 函數做爲參數
    由於函數也是一種類型,能夠把函數做爲兩一個函數的參數,在另外一個函數中調用
  • 函數做爲返回值
    由於函數是一種類型,因此能夠把函數做爲返回值從函數內部返回
function fn(b) {
    var a = 10;
    return function() {
        alert(a + b);
    }
}
fn(15)();
複製代碼

做用域

做用域:變量能夠起做用的範圍
複製代碼

全局變量和局部變量

全局變量

 在任何地方均可以訪問到的變量就是全局變量,對應全局做用域

 局部變量

 只在固定的代碼片斷內可訪問到的變量,最多見的例如函數內部。對應局部做用域(函數做用域)
複製代碼

變量退出做用域以後會銷燬,全局變量關閉網頁或瀏覽器纔會銷燬瀏覽器

function fn() {
    var num = 5;
}
console.log(num)   //num is not defined
//函數內部定義的變量num是局部變量,在外部不能夠訪問
複製代碼

做用域鏈

只有函數能夠製造做用域結構,那麼只要是代碼,就至少有一個做用域,即全局做用域。
凡是代碼中有函數,那麼這個函數就構成另外一個做用域。
若是函數中還有函數,那麼在這個做用域中就又能夠誕生一個做用域。
複製代碼

將這樣的全部的做用域列出來造成做用域鏈 : 函數內指向函數外的鏈式結構。代碼在運行時,先在函數內部找變量,找不到再去函數外找bash

// 全局做用域 -- 0級做用域鏈
var num = 5;
function f1() {
  // f1 局部做用域 -- 1級做用域鏈
  // var num = 15;
  function f2() { 
    // f2 局部做用域 -- 2級做用域鏈
    console.log(num);
  }
  f2();
}
f1();
複製代碼

預解析 -- 變量提高

預解析過程:函數

  1. 把變量的聲明提高到當前做用域的最前面,只會提高聲明,不會提高賦值
  2. 把函數的聲明提高到當前做用域的最前面,只會提高聲明,不會提高調用
  3. 先提高var,再提高function
  4. 提高完後其餘代碼位置不變
1var a = 25;
    function abc() {
        alert(a); 
        var a = 10;
    }
    abc();
    
   預解析後以下:
    var a;
    function abc() {
        var a;
        alert(a);
        a = 10;
    }
    a = 25;
    abc();  //ndefined;
複製代碼
2:
    var a = 18;
    f1();
    function f1() {
      var b = 9;
      console.log(a);
      console.log(b);
      var a = '123';
    }
    
   預解析後以下:
    var a;
    function f1() {
        var b;
        var a;
        b = 9;
        console.log(a);
        console.log(b);
        a = '123';
    }
    a = 18;
    f1();
    // undefined 
    // 9
複製代碼

對象

爲何要有對象

function printPerson(name, age, sex....) {
}
// 函數參數不少的化,能夠傳入對象簡化
function printPerson(person) {
    console.log(person.name)
}
複製代碼

什麼是對象

現實生活中,萬物皆對象,好比一輛車,一部手機。
對象是一個具體的事物,事物就會有特徵和行爲。
js中的對象是生活中對象的抽象,能夠把JavaScript中的對象想象成鍵值對,其中值能夠是數據(對象字面量)和函數。
對象的行爲和特徵:
    特徵---屬性
    行爲---方法

思考:狗是對象嗎?我認爲狗不是對象,狗描述了一類事物,但我家的薩摩耶是一個對象
複製代碼
對象和函數有類似性,函數封裝了代碼,可重用;對象封裝了一組屬性和方法,一樣可重用。
複製代碼

對象建立方式

對象字面量

建立小明對象,小明具備的 屬性有  name,age等,方法有 打招呼
複製代碼
var o = {
  name: 'zs',
  age: 18,
  sex: true,
  //在方法中如何使用對象的屬性呢?用this.
  //this表明的是當前對象
  sayHi: function () {
    console.log(this.name + '你好');
  }
  }

//訪問對象的屬性    console.log(o.name) 或 console.log(o['name'])
//訪問對象的方法    o.saiHi()
複製代碼
思考:函數和方法的區別:方法是對象的函數;經過 o.sayHi()調用
複製代碼

new Object()

經過new來建立構造函數

var person = new Object();   //new Object()調用構造函數;在內存中建立了一個空的對象,
而後能夠經過動態的方式給對象添加屬性和方法。體現了js的動態性
person.name = 'monster'
person.sayHi = function() {
console.log('Hello,everyBody');
}
複製代碼

工廠模式批量建立對象

function createPerson(name,age,job) {
    var person = new Object();
    person.name = name;
    person.age = age;
    person.job = job;
    person.sayHi = function(){
        console.log('Hello,everyBody');
  };
  return person;
}
var p1 = createPerson('monster',23,'cleaner')
複製代碼

自定義構造函數(推薦)

function Person(name,age,job) {
    this.name = name;       //this指向當前對象,this.name動態的爲對象添加name 屬性,而且使name的值等於傳過來參數的值
    //注意形參的名字要和後面的name同樣;好比傳過來的形參是a,那麼this.name = a
    this.age = age;
    this.job = job;
    this.sayHi = function(){
  	console.log('Hello,everyBody');
  }
}
var p1 = new Person('monster',23,'cleaner')
複製代碼
注意:
1. 構造函數用於建立一類對象,首字母要大寫。

還記得狗狗這一類吧,構造函數至關於建立了「狗」類,而後隨便你要什麼狗,
哈士奇,泰迪,直接new Dog('二哈','白色') 建立狗這個對象。。
2. 構造函數要和new一塊兒使用纔有意義。
複製代碼
new在執行時會作四件事情:

new會在內存中建立一個新的空對象
new 會讓this指向這個新的對象
執行構造函數  目的:給這個新對象加屬性和方法
new會返回這個新對象
複製代碼

this

this的指向問題仍是挺讓人頭疼的,實驗結果以下ui

1.函數中的this  -----> 指向window
 function fn() {
     console.log(this);
 }
 fn()
 
2.方法中的this  -----> 指向方法所屬的對象
var obj = {
    name : 'monster',  //注意逗號結尾
    fn : function() {
        console.log(this)
    }
}
obj.fn()

3.構造函數中的this  ----->   指向構造函數建立的對象
function Fn() {
this.name = 'monster'
    console.log(this)
}
var o = new Fn()  //調用構造函數
若是經過 Fn() 調用, 結果是指向window,覺得是調用函數
複製代碼
總結:
1. 函數在定義的時候this是不肯定的,只有在調用的時候才能夠肯定
2. 通常函數直接執行,內部this指向全局window
3. 函數做爲一個對象的方法,被該對象所調用,那麼this指向的是該對象
4. 構造函數中的this實際上是一個隱式對象,相似一個初始化的模型,全部方法和屬性都掛載到了這個隱式對象身上,後續經過new關鍵字來調用,從而實現實例化
複製代碼

遍歷和刪除對象屬性

遍歷

for in 能夠遍歷對象的屬性成員

var obj = {
  name: 'zs',
  age: 18,
  sex: true,
  sayHi: function () {
    console.log(this.name + '你好');
  }
  }
  for (var key in obj)  //key 是對象的屬性成員
  { 
    console.log(key + '---' + obj[key]) ;
  }
  //答應對象的屬性和對應的值
複製代碼
能夠經過循環的方式動態給對象增長屬性

var o = {};
for (var i = 0; i < 10; i++) {
    o[a + 'i'] = i * 2;
}
複製代碼

刪除

經過delete刪除


function Fun() {
    this.name = 'monster'
}
var obj = new Fun()
console.log(obj.name); // monster
delete obj.name
console.log(obj.name); // undefined


複製代碼

總結完這些不知不覺已經快深夜2點了~~
若是對您有幫助,就麻煩點個贊吧,歡迎交流this

相關文章
相關標籤/搜索