小编吐血整理加上翻译,太辛苦了~求赞!html
本文主要总结了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 定义变量。
从ES5开始, 严格模式用于检测运行时的错误,在严格模式下,全部的变量必须声明,若是给未声明的变量赋值会抛出异常。
在JavaScript 文件或<Script>元素内,经过输入如下代码切换到严格模式:
use strict;
建议采用严格模式,除非项目依赖的库不兼容严格模式。
JS中的对象概念不一样于OO或UML中的对象,尤为是在JS中对象不须要实例化,也能够有本身的方法,不只有property slots,也包含method slots。除此以外还包含key-value slots;所以他们总共有三种Slots, 而常见的对象只有属性槽。
JS对象是由一系列的name-value 组成的Slot。而name 能够是属性名称,函数名称,映射名称。对象可经过一种特定的方式建立,使用JS 对象声明语法(JSON),而不须要实例化一个类。代码以下:
var person1 = { lastName:"Smith", firstName:"Tom"}; var o1 = Object.create( null); // an empty object with no slots
若是Slot 的name 是合法的JS 标识符,则Slot可表示属性,方法,或键值对。若是名称含有一些特殊字符如空格,则Slot表明键值对,是一种映射元素,以下:
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[i]); }
若是数组较小,可以使用foreach 循环:
a.forEach( function (elem) { console.log( elem); })
JS 也提供克隆数组的函数:
var clone = a.slice(0);
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[i]; console.log( m[key]); }
若是map 较小可以使用foreach 语句:
Object.keys( m).forEach( function (key) { console.log( m[key]); })
复制map
var clone = JSON.parse( JSON.stringify( m))
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[i]; } 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都须要使用类,所以常常须要定义类之间的关系,因此必须保证,使用相同类
只有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 定义类层次的静态属性
Person.instances = {};
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 Person Student.prototype = Object.create( Person.prototype); // adjust the subtype's constructor property Student.prototype.constructor = Student;
Step2c, 从新定义子类方法重写超类方法:
Student.prototype.toString = function () { return Person.prototype.toString.call( this) + "(" + this.studNo + ")"; };
基于构造器类的实例化是经过应用new 操做符来建立的,并提供合适的构造参数:
var pers1 = new Person("Tom","Smith");
方法toString 经过pers1. 来调用:
alert("The full name of the person are: " +
pers1.toString());
在JS中,prototype 是具备method slots 的对象,能够经过JS方法或属性槽继承的。
在该方法中定义了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;如上面第五行的。
学习了本节内容,有助于你们更好地使用JavaScript进行Web应用的开发。在开发过程当中,还能够借助一些开发工具,好比 Wijmo 和 SpreadJS。其中Wijmo是为企业应用程序开发而推出的一系列包含 HTML5 和 JavaScript 的开发控件,不管应用程序是移动端、PC端、仍是必需要支持IE6,Wijmo 均能知足需求。而SpreadJS纯前端表格控件是基于 HTML5 的 JavaScript 电子表格和网格功能控件,适用于.NET、Java 和移动端等各平台在线编辑类 Excel 功能的表格程序开发。