來源於:http://gcdn.gcpowertools.com.cn/showtopic-28404-1-3.html?utm_source=gold.xitu.io&utm_medium=referral&utm_campaign=20161220html
本文主要總結了JavaScript 經常使用功能總結,如一些經常使用的JS 對象,基本數據結構,功能函數等,還有一些經常使用的設計模式。前端
目錄:正則表達式
衆所周知,JavaScript是動態的面向對象的編程語言,可以實現如下效果:編程
1. 豐富Web 網頁功能設計模式
2. 豐富Web界面數組
3. 實現本地或遠程存儲。網絡
4. 實現分佈式網絡應用的前端組件,並在後臺進行數據存儲管理。數據結構
5. 使用JavaScript能夠實現完整的分佈式Web 應用。app
JavaScript 中的數據類型框架
JavaScript 提供三種元數據類型,string,number,和Boolean,可以使用typeof(v) 測試變量V 的類型,typeof(v)==="number"
提供五種基本的引用類型:Object, Array, Function, Date 及RegExp。數組,函數,日期和正則表達式是特殊類型,可是嚴格來說,日期和正則表達式是元數據類型,可封裝在其餘對象中。
JS 中變量類型,數組元素類型,函數參數以及返回值的類型不須要聲明類型,類型之間的轉換是自動執行的。
變量值能夠是:
1. 數值:如字符串,數字或布爾值。
2. 對象引用: 可引用典型對象,也能夠是數據,函數,日期或正則表達式。
3. 特殊數據值,Null,是典型的用於初始化對象的默認值。
4. 特殊數據undefined,經常使用於已被定義,但未賦值的變量。
string 是一系列的Unicode 字符串,String 如「hello world」,’A3FO’或空字符串「」,字符串鏈接可經過+操做符來執行,也可使用=號來驗證兩個字符串是否相等;
if (firstName + lastName === "James Bond") ...
numeric 表示64位的浮點數,在JS 中沒有明顯的區分整形和浮點數,若是一個表達式的值不等於某個數字,那麼它的值可設爲NaN,表示非數字,可聯合isNaN使用。
以下表是詳細的類型測試和轉換
變量做用域範圍
目前,JavaScript,ES5提供兩種做用域類型:全局變量及函數做用域,沒有塊做用域。塊做用域的範圍不太明確,因此應當避免塊做用域的使用。以下代碼,儘管是開發人員經常使用的Pattern,倒是一個陷阱。
function foo() {
for (var i=0; i < 10; i++) {
... // do something with i
}
}
全部的變量聲明最好是在函數的開始位置。在JS,ES6版本中支持塊做用域,採用關鍵字let 定義變量。
嚴格模式(Strict Mode)
從ES5開始, 嚴格模式用於檢測運行時的錯誤,在嚴格模式下,全部的變量必須聲明,若是給未聲明的變量賦值會拋出異常。
在JavaScript 文件或<Script>元素內,經過輸入如下代碼切換到嚴格模式:
use strict;
建議採用嚴格模式,除非項目依賴的庫不兼容嚴格模式。
多種對象
JS中的對象概念不一樣於OO或UML中的對象,尤爲是在JS中對象不須要實例化,也能夠有本身的方法,不只有property slots,也包含method slots。除此以外還包含key-value slots;所以他們總共有三種Slots, 而常見的對象只有屬性槽。
JS對象是由一系列的name-value 組成的Slot。而name 能夠是屬性名稱,函數名稱,映射名稱。對象可經過一種特定的方式建立,使用JS 對象聲明語法(JSON),而不須要實例化一個類。
代碼以下:
Property Slot 中的name:
1. data value 屬性,在這種狀況下,Value 表示變量值,或是值表達式。
2. object-valued 屬性,Value 表示對象的引用或對象表達式。
method Slot 表示的是JS 函數,它的值是JS 函數定義表達式:
Object 屬性可使用兩種方法來訪問:
1. 使用」.」(與C++ 和Java的相似):
person1.lastName = "Smith"
2. 使用map:
person1["lastName"] = "Smith"
JS 對象可以用於各類途徑,如下是五種常見狀況:
1. Record是Property slots集合,如:
var myRecord = {firstName:"Tom", lastName:"Smith", age:26}
2. map 如Hash map,數組,hash表;
var numeral2number = {"one":"1", "two":"2", "three":"3"}
3. Untyped 對象不須要實例化類,它可能包含property slot 和function slots:
var person1 = {
lastName: "Smith",
firstName: "Tom",
getFullName: function () {
return this.firstName +" "+ this.lastName;
}
};
Array List
JS array 即邏輯數據結構,經過數組下標訪問。如數組初始化:
var a = [1,2,3];
JS數組可動態增加,所以數組索引有可能比實際元素個數多,以下:
a[4] = 7;
數組循環:
for (i=0; i < a.length; i++) { ...}
數組是特殊的對象類型,所以有不少狀況下,須要判斷變量是否爲數組類型,使用IsArray方法:Array.isArray( a)。
添加新元素到數組:
a.push( newElement);
刪除:
a.splice( i, 1);
查找:
if (a.indexOf(v) > -1) ...
循環:
var i=0;
for (i=0; i < a.length; i++) {
console.log( a);
}
若是數組較小,可以使用foreach 循環:
a.forEach( function (elem) {
console.log( elem);
})
JS 也提供克隆數組的函數:
var clone = a.slice(0);
Maps
map 提供key 到值得映射。JS map 是一串字符集,可包含空格:
var myTranslation = {
"my house": "mein Haus",
"my boat": "mein Boot",
"my horse": "mein Pferd"
}
增長:
myTranslation["my car"] = "mein Auto";
刪除:
myTranslation["my car"] = "mein Auto";
查找:
if ("my bike" in myTranslation) ...
循環:
var i=0, key="", keys=[];
keys = Object.keys( m);
for (i=0; i < keys.length; i++) {
key = keys;
console.log( m[key]);
}
若是map 較小可以使用foreach 語句:
Object.keys( m).forEach( function (key) {
console.log( m[key]);
})
複製map
var clone = JSON.parse( JSON.stringify( m))
小結:JavaScript 支持4種基本的數據結構。
1:array lists:如["one","two","three"],special JS對象
2:records:特殊的JS 對象,如{firstName:"Tom", lastName:"Smith"};
3:maps: 如{"one":1, "two":2, "three":3}
4:entity 表:以下表所示,是一種特殊的map,值是有固定ID的記錄。
record,map,entity 在實際應用中沒有明顯的區分,只是概念上的區分。對JS 引擎而言,都是對象。可是從概念上是有區分的。
函數
如表1 所示,函數是特殊的JS 對象,有name 屬性和length屬性表示參數的個數,以下,判斷v是否指向函數:
if (typeof( v) === "function") {...}
函數定義:
var myFunction = function theNameOfMyFunction () {...}
theNameOfMyFunction 是可選的,若是省略函數名稱,則稱該函數爲匿名函數。一般,函數是經過變量來調用的,如上面的代碼,則表示
myFunction 會調用myFunction()函數,而不是使用theNameOfMyFunction()調用。
匿名函數表達式在其餘編程語言中稱爲lambda 表達式。以下代碼是匿名函數。能夠與預約義的sort函數對比:
var list = [[1,2],[1,3],[1,1],[2,1]];
list.sort( function (x,y) {
return ((x[0] === y[0]) ? x[1]-y[1] : x[0]-y[0]);
});
函數聲明:
function theNameOfMyFunction () {...}
與代碼
var theNameOfMyFunction = function theNameOfMyFunction () {...}
等價;
聲明瞭函數theNameOfMyFunction ,並使用theNameOfMyFunction 變量來引用函數。
JS 提供函數內聯,closure機制容許JS 函數調用函數以外的使用變量。函數能夠建立closure 來存儲當前的環境。以下,不須要經過參數將外部變量的結果傳給內部函數,它自己就是可用的。
var sum = function (numbers) {
var result = 0;
numbers.forEach( function (n) {
result += n;
});
return result;
};
console.log( sum([1,2,3,4]));
當執行一個方法時,可使用內置arguments 對象訪問函數內的參數,arguments 對象與數組使用方法相似,有長度屬性,也有索引,而且可使用For語句來循環迭代。可是因爲它並非Array 實例,所以JS arrary的部分方法沒法應用如foreach。
arguments 對象的元素個數與函數參數個數相同,也能夠定義方法的時候不指定參數個數,在調用時,可爲函數賦多個參數,如:
var sum = function () {
var result = 0, i=0;
for (i=0; i < arguments.length; i++) {
result = result + arguments;
}
return result;
};
console.log( sum(0,1,1,2,3,5,8)); // 20
方法是在構造函數的原型上定義的,能夠經過對象建立的構造器調用,如Array.prototype.forEach;Array表示構造器,調用類的實例做爲上下文對象參考的,以下: 在foreach中numbers表示上下文對象:
var numbers = [1,2,3]; // create an instance of Array
numbers.forEach( function (n) {
console.log( n);
});
不管原型方法是否被上下文對象調用,可是隻要是參數爲對象,可使用JS函數的Call 方法來輔助調用對象。以下,咱們可使用foreach 循環方法:
var sum = function () {
var result = 0;
Array.prototype.forEach.call( arguments, function (n) {
result = result + n;
});
return result;
};
Function.prototype.call方法和apply都是爲了改變某個函數運行時的 context 即上下文而存在的。
定義和使用類
類是面向對象中的基本概念,對象的實例化稱爲類。JS中定義類須要知足如下五個需求:1.指定類的名稱,實例級別的屬性和方法,類級別的屬性和方法。2. 是可預測的實力,可以用於驗證是不是某一對象的實例。3. 實例級別的屬性用於檢測對象的直接類型。4. 屬性繼承5.方法繼承。
除此以外還支持對哦集成和多分類。
JS中對類沒有統一的定義規範,可使用不一樣代碼模式來定義類,並應用於多種不一樣的框架。JS中最經常使用的定義類的方法以下:
1. 構造函數規範,可經過prototype chain實現方法繼承,並支持建立新的類實例。
2. factory 對象,用於預約義Object.create 方法來建立新實例。該方法中基於構造函數的繼承機制能夠被其餘機制代替。
建立App都須要使用類,所以常常須要定義類之間的關係,因此必須保證,使用相同類
Constructor-based classes
只有ES6引入了定義基於構造器的類。新語法支持定義一些簡單的類繼承,具體步驟以下:
Step 1.a 基類Person 具備兩個屬性,first Name 和Last Name,實例層的方法toString和靜態方法checkLastName;
class Person {
constructor( first, last) {
this.firstName = first;
this.lastName = last;
}
toString() {
return this.firstName + " " +
this.lastName;
}
static checkLastName( ln) {
if (typeof(ln)!=="string" ||
ln.trim()==="") {
console.log("Error: " +
"invalid last name!");
}
}
}
Step 1.b 類層次的屬性定義:
Person.instances = {};
在第二步中,會定義一個帶有其餘屬性和方法的子類,也有可能重寫父類的相關方法:
class Student extends Person { constructor( first, last, studNo) {
super.constructor( first, last);
this.studNo = studNo;
}
// method overrides superclass method
toString() {
return super.toString() + "(" +
this.studNo +")";
}
}
ES5中,能夠定義繼承基於構造器類的子類。以下:
Step1.a 首先定義構造函數,可以隱式的定義類的屬性並賦值;
function Person( first, last) {
this.firstName = first;
this.lastName = last;
}
注意,上述代碼中的this 指的是新生成的對象,當構造函數被調用時,該對象就已經生成了。
Step1.b 定義實例層的方法:
Person.prototype.toString = function () {
return this.firstName + " " + this.lastName;
}
Step 1.c 定義靜態方法:
Person.checkLastName = function (ln) {
if (typeof(ln)!=="string" || ln.trim()==="") {
console.log("Error: invalid last name!");
}
}
Step 1.d 定義類層次的靜態屬性
Step 2.a 定義子類:
1: function Student( first, last, studNo) {
2: // invoke superclass constructor
3: Person.call( this, first, last);
4: // define and assign additional properties
5: this.studNo = studNo;
6: }
經過調用超類的構造函數Person.call( this, ...),來建立新對象。其中This指的是Student,Property Slots 在超類的構造函數中已經建立((firstName 和lastName) 以及其餘子類相關的屬性。在這種狀況下可以使用Property Inheritance 機制保證全部的屬性已經被定義且被建立。
Step2b,經過構造函數的prototype 屬性安裝method inheritance 。以下,分配了一個新對象建立子類型構造函數的Prototype 屬性,並作出適當的調整:
// Student inherits from PersonStudent.prototype = Object.create( Person.prototype);// adjust the subtype's constructor propertyStudent.prototype.constructor = Student;
Step2c, 從新定義子類方法重寫超類方法:
// Student inherits from Person
Student.prototype = Object.create(
Person.prototype);
// adjust the subtype's constructor property
Student.prototype.constructor = Student;
基於構造器類的實例化是經過應用new 操做符來建立的,並提供合適的構造參數:
Student.prototype.toString = function () {
return Person.prototype.toString.call( this) +
"(" + this.studNo + ")";
};
方法toString 經過pers1. 來調用:
alert("The full name of the person are: " + pers1.toString());
在JS中,prototype 是具備method slots 的對象,能夠經過JS方法或屬性槽繼承的。
基於Factory 的類
在該方法中定義了JS 對象Person,含有特殊的Create 方法來調用預約義的Object.Create方法,建立Person類型的對象;
var Person = {
name: "Person",
properties: {
firstName: {range:"NonEmptyString", label:"First name",
writable: true, enumerable: true},
lastName: {range:"NonEmptyString", label:"Last name",
writable: true, enumerable: true}
},
methods: {
getFullName: function () {
return this.firstName +" "+ this.lastName;
}
},
create: function (slots) {
// create object
var obj = Object.create( this.methods, this.properties);
// add special property for *direct type* of object
Object.defineProperty( obj, "type",
{value: this, writable: false, enumerable: true});
// initialize object
Object.keys( slots).forEach( function (prop) {
if (prop in this.properties) obj[prop] = slots[prop];
})
return obj;
}
};
注意JS對象Person實際表示的是factory-based 類。factory-based類的實例化是經過調用它本身的Create方法實現的:
var pers1 = Person.create( {firstName:"Tom", lastName:"Smith"});
getFullName 方法是經過pers1. 調用的,以下:
alert("The full name of the person are: " + pers1.getFullName());
每一個屬性的聲明都是使用Object.Create 聲明的,其中包含三個參數及值,'descriptors'writable: true and enumerable: true;如上面第五行的。