JavaScript基础总结

来源:互联网 发布:编程一小时网站登录 编辑:程序博客网 时间:2024/06/13 16:43

其实一直没有正式的学习过JavaScript(后面简称JS),但是由于JS是一门使用范围很广的语言,可以说接触过Web开发的童鞋就必定用过JS,而我作为一名半吊子的开发者,自然也是断断续续的用过JS的,但是用的很少。因为最近在研究移动混合开发方便的一些知识,准备开始啃angular js这块骨头了,但是鉴于自己的JS基础知识不牢靠,还是先在这里总结下JS的基础知识,再去啃angular js。

1、基本总结

下面就来针对JS进行一些基本总结吧。

1.1、变量和常量

JS中与变量常量声明相关的关键字有varlet以及const,其中let和const是ES6的新特性。var和let都是用来声明变量的,不同的是var声明的变量会有一个一个作用域提升的效果,var 声明的变量会被提升到当前作用域的最前面,它的作用域范围也就是当前作用域,即使它是在语句块中声明。而let声明的变量就没有作用域提升的效果,它声明的变量会绑定当前语句块(暂时性死区,temporal dead zone,简称TDZ),被声明之后才可以使用,只在声明所在的块级作用域内有效。const关键字用来声明常量,同时它声明的常量也和let一样不存在作用域提升的效果。

function foo(){  //if中的声明语句会被提升到这里  //var a;  if(false) {    var a = 1;  }  a = 10;  console.log(a);//10}function bar(){  {    console.log(b); //ReferenceError: can't access lexical declaration `b' before initialization    let b = 2;  }  console.log(b); //ReferenceError: b is not defined}function baz(){  {    const c = 2;  }  console.log(c); //ReferenceError: c is not defined}

1.2、函数

JS中的函数实际上是一个对象,每个函数都是Function类型实例,而且可以与其它引用类型一样具有属性和方法,由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,可以作为变量指向其它函数对象,也可以作为其它函数的返回值。

常用的函数定义方式有两种

一种是声明式定义

function sum (num1, num2) {  return num1 + num2;}

还有一种是表达式定义

var sum = function(num1, num2){  return num1 + num2;};

声明式定义和表达式定义的函数完全一致,上面也提到函数实际上是一个Function对象,所以函数实际上还可以通过实例化Function对象的方式来定义

var sum = new Function("num1", "num2", "return num1 + num2"); 

但是一般不推荐这种定义方式,因为这种语法会导致解析两次代码(第一次是解析常规 ECMAScript 代码,第二次是解析传入构造函数中的字符串)。

函数本身是一个对象,其中存在类方法、对象方法以及原型方法(prototype func)三种方方法,对面向对象编程熟悉的童鞋肯定对类方法和对象方法不会陌生,但是原型方法就不知所云了,这里想举出三种方法的实现。

function People(name){  this.name=name;  //对象方法  this.Introduce=function(){    alert("My name is "+this.name);  }}//类方法People.Run=function(){  alert("I can run");}//原型方法People.prototype.IntroduceChinese=function(){  alert("我的名字是"+this.name);}

例子中声明了一个名为People的函数,并分别实现了People中的对象方法、类方法以及原型方法(要注意这里说的方法实际上也是函数)。这里对原型方法不深入讲,只需要记住有这么一个队函数的方法扩展就行了。

1.3、数据类型

JS有七种数据类型,分别是Undefined、Null、Boolean、String、Symbol、Number以及Object,前面六种是基本数据类型,后面的Object是引用数据类型,基本数据类型是有限集数据类型(其对应的数据是有限的,如Boolean制度应true和false两个数据),而Object是无限集数据类型。

Undefined: 表示变量还没有声明

Null: 表示Object类型变量没有引用对象

Boolean: 布尔值类型

String: 字符串类型

Symbol:这是ES6语法新特性定义的数据类型,任何两个Symbol值不一样

Number: 数值类型

Object:对象类型

关于Symbol数据类型感兴趣的同学可以去看看参考文献4。另外针对数据类型,有两个方法得在这里说说,即typeof 以及 instanceof,typeof用来获取一个变量或者表达式的类型,typeof一般只能返回如下几个结果:

  • “undefined” 如果这个值未定义
  • “boolean” 如果这个值是布尔值
  • “string” 如果这个值是字符串
  • “number” 如果这个值是数值
  • “object” 如果这个值是对象或者null
  • “function” 如果这个值是函数
  • “symbol” 如果这个值是Symbol类型(ES6新增)

typeof方法在遇到null,数组,对象时都会返回object类型,所以当我们要判断一个对象是否是数组时
或者判断某个变量是否是某个对象的实例则要选择使用另一个关键语法instanceof,instanceof用于判断一个变量是否某个对象的实例,下面的代码会返回true

var a=new Array();alert(a instanceof Array);

而因为Array是object的子类,所以下面的代码也会返回true

var a=new Array();alert(a instanceof Object);

从例子中可以看出typeof是一个单目运算符,typeof可以用于判断变量是否为简单类型对象,但是typeof使用最多的地方是检测一个对象是否已经定义或者是否已经赋值。

而instanceof是双目运算符,其左侧是对象变量,右侧是数据类型,一般用来判断对象变量的具体对象类型,由上面例子也能看到instanceof在判断Array类型变量时也会认为其是Object类型,所以instanceof往往不用来判断基本的对象类型,而用来判断用户自定义对象类型。

总的来说就是简单类型的变量由typeof来检测,而对象类型变量由instanceof来检测,另外JS 标准文档给出了一种获取 [[Class]] 值的方法来精确的获取变量的数据类型,那就是使用 Object.prototype.toString

function is(type, obj) {    var clas = Object.prototype.toString.call(obj).slice(8, -1);    return obj !== undefined && obj !== null && clas === type;}is('String', 'test'); // trueis('String', new String('test')); // true

实际上Object.prototype.toString 返回一种标准格式字符串

Object.prototype.toString.call([])    // "[object Array]"Object.prototype.toString.call({})    // "[object Object]"Object.prototype.toString.call(2)    // "[object Number]"

1.4、模块

ES6中引入了模块的概念,之前我们引用其它JS都是通过script标签来完成的,在ES6中,我么可以通过import和export这两个关键字来完成这个事情了,而且更加的灵活简单。export负责导出,而import负责导入,导出和导入的内容就是模块(module).

import花括号里面的变量名必须与导出的变量名相同,但是可以通过as起别名

//导出过程var name = 'yjing';var year = 1990;export  {name,year};//导入过程import {name as nickName,year as myYear} from './study.js';alert(nickName);

这里的导出和导入的代码都是写在同一个study.js文件中的。

1.5、原型

原型(prototype)这个概念在JS中算是比价复杂的概念了,上面在讲函数的时候也提到了原型方法的使用。我们知道在面前对象的编程中,我们一个类要实现另一个类的方法可以通过继承的方式来完成,那么在JS中怎么办呢,在ES6之前(ES6支持类的继承了),就是使用prototype,但是prototype不是真正的继承,而是克隆代码,就比如继承时A继承B,那B就不能继承A了,大师prototype不一样,A的prototype可以是B,同时B的prototype也可以是A。

JS中每个对象类型都有一个prototype属性,可以将其它对象实例赋值给它,使得该对象类型获得其它对象类型的属性、方法,也可以直接通过prototype对该对象类型进行方法扩展。

function baseClass(){  this.showMsg = function()  {     alert("baseClass::showMsg");     }}function extendClass(){}extendClass.prototype = new baseClass();var instance = new extendClass();instance.showMsg(); // 显示baseClass::showMsg

这个例子中extendClass类通过prototype获取了baseClass类的方法。

function People(name){  this.name=name;  //对象方法  this.Introduce=function(){    alert("My name is "+this.name);  }}//原型方法People.prototype.IntroduceChinese=function(){  alert("我的名字是"+this.name);}

而这个例子中,通过队People这个对象类型的prototype进行扩展使得People这个类拥有了IntroduceChinese这个方法。

以上就是我关于JS的一些简单总结,如果以后有新的总结内容,还会继续添加。

2、参考文献

我自己其实关于JS没什么认识,本文的知识点基本都是从下面几篇参考文献中而来,谢谢这些同学的奉献。

1、JavaScript 总结

2、JS中的prototype

3、js中typeof与instanceof用法

4、【探秘ES6】系列专栏(八):JS的第七种基本类型Symbols

5、JavaScript 数据类型

6、js使用总结