Javascript基础

阅读目录:

 

一、Javascript简介

1.概念

  JavaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标准通用标记语言下的一个应用)网页上使用,用来给HTML网页增加动态功能。
  在1995年时,由Netscape公司的Brendan Eich,在网景导航者浏览器上首次设计实现而成。因为Netscape与Sun合作,Netscape管理层希望它外观看起来像Java,因此取名为JavaScript。但实际上它的语法风格与Self及Scheme较为接近。 [1] 
为了取得技术优势,微软推出了JScript,CEnvi推出ScriptEase,与JavaScript同样可在浏览器上运行。为了统一规格,因为JavaScript兼容于ECMA标准,因此也称为ECMAScript。
 
 

注:ES6就是指ECMAScript 6。

尽管 ECMAScript 是一个重要的标准,但它并不是 JavaScript 唯一的部分,当然,也不是唯一被标准化的部分。实际上,一个完整的 JavaScript 实现是由以下 3 个不同部分组成的:

  • 核心(ECMAScript) 由ECMA-262定义,提供核心语言功能(ECMA是欧洲计算机制造商协会)
  • 文档对象模型(DOM) Document object model (整合js,css,html) 提供访问和操作网页内容的方法和接口
  • 浏览器对象模型(BOM) Broswer object model(整合js和浏览器)提供与浏览器交互的方法和接口

 

2.注释
  • 单行注释 //
  • 多行注释  /*内容*/
单行注释
//  这是单行注释
    
多行注释
/*
这是
多行注释
*/

 

3.引入文件

  a.引入外部js文件
<script src="myscript.js"></script>

  

  b.存放在HTML的<head>或<body>中

<script type="text/javascript">
    Js代码内容
</script>

  

 4.语言规范
  JavaScript中的语句要以分号(;)为结束符。
 
 5.声明变量
  • JavaScript的变量名可以使用_,数字,字母,$组成,不能以数字开头。
  • 声明变量使用 var 变量名; 的格式来进行声明

注意:

  • 变量名是区分大小写的。
  • 推荐使用驼峰式命名规则。
  • 保留字不能用做变量名。

补充:

ES6新增了let命令,用于声明变量。其用法类似于var,但是所声明的变量只在let命令所在的代码块内有效。例如:for循环的计数器就很适合使用let命令。

for (let i=0;i<arr.length;i++){...}

 

ES6新增const用来声明常量。一旦声明,其值就不能改变。 

const PI = 3.1415;
PI // 3.1415

PI = 3
// TypeError: "PI" is read-only

 

abstract
boolean
byte
char
class
const
debugger
double
enum
export
extends
final
float
goto
implements
import
int
interface
long
native
package
private
protected
public
short
static
super
synchronized
throws
transient
volatile
保留字列表

  

 二、数据类型

在 JavaScript 中有 5 种不同的数据类型:

    • string
    • number
    • boolean
    • object
    • function

3 种对象类型:

    • Object
    • Date
    • Array

2 个不包含任何值的数据类型:

    • null
    • undefined
1.数字(Number)
  JavaScript不区分整型和浮点型,就只有一种数字类型。
 
  转换:
  • parseInt(..)    将某值转换成整数,不成功则NaN
  • parseFloat(..) 将某值转换成浮点数,不成功则NaN
   NaN not a number 不是一个数字

  特殊值:

  •  NaN,非数字。可以使用 isNaN(num) 来判断。
  • Infinity,无穷大。可以使用 isFinite(num) 来判断。
Number.MAX_VALUE 最大数值
Number.MIN_VALUE 最小数值
Number.NaN 非数字
Number.NEGATIVE_INFINITY 负无穷大
Number.POSITIVE_INFINITY 正无穷大
Number.toExponential( ) 返回四舍五入的科学计数法,加参数为保留几位
Number.toFixed( ) 小数点后面的数字四舍五入,加参数为保留几位
Number.toPrecision( ) 四舍五入,自动调用toFixed()或toExponential()
Number.toLocaleString( ) 把数字转换成本地格式的字符串
Number.toString( ) 将数字转换成字符串
Number.valueOf( ) 返回原始数值

 

 1 var a = 12.34;
 2 var b = 20;
 3 var c = 123e5;  // 12300000
 4 var d = 123e-5;  // 0.00123
 5 undefined
 6 a
 7 12.34
 8 b
 9 20
10 c
11 12300000
12 d
13 0.00123
14 parseInt(a)
15 12
16 parseInt(b)
17 20
18 parseInt(c)
19 12300000
20 parseInt(d)
21 0
数字类型示例

 

2.字符串(String)

var a = "Hello"
var b = "world;
var c = a + b; 
console.log(c);  // 得到Helloworld

 

  常用方法: 

String.length 字符串的长度
String.trim() 移除空白
String.trimLeft() 移除左侧空白
String.trimRight() 移除右侧空白
String.concat(value, ...) 拼接
String.slice(start, end) 切片
String.split( ) 分割
String.search( ) 从头开始匹配,返回匹配成功的第一个位置(g无效)
String.match( ) 全局搜索,如果正则中有g表示找到全部,否则只找到第一个
String.replace( ) 替换,正则中有g则替换所有,否则只替换第一个匹配项;
$数字:匹配的第n个组内容;
$&:当前匹配的内容;
$`:位于匹配子串左侧的文本;
$':位于匹配子串右侧的文本
$$:直接量$符号
String.charAt( ) 返回字符串中的第n个字符
String.charCodeAt( ) 返回字符串中的第n个字符的代码
String.fromCharCode( ) 从字符编码创建—个字符串
String.indexOf( ) 查找子字符串位置
String.lastIndexOf( ) 查找子字符串位置
String.localeCompare( ) 用本地特定的顺序来比较两个字符串
String.substr( ) 抽取一个子串
String.substring( ) 返回字符串的一个子串
String.toLocaleLowerCase( ) 把字符串转换小写(针对地区,在不知道程序在哪个语言环境中运行时用)
String.toLocaleUpperCase( ) 将字符串转换成大写(针对地区)
String.toLowerCase( ) 小写
String.toUpperCase( ) 大写
String.toString( ) 返回原始字符串值
String.toString() 返回原始字符串值
String.valueOf( ) 返回原始字符串值

 

1 \0 空字节
2 \n 换行
3 \t 制表
4 \b 空格
5 \r 回车
6 \f 进纸
7 \\ 斜杠
8 \' 单引号
9 \" 双引号
转义字符

 

var s1 = "  fex l i x  "
s1.length
// 13
s1.trim()
// "fex l i x"

s1.trimLeft()
// "fex l i x  "
s1.trimRight()
// "  fex l i x"
s1.charAt(8)
// "i"
s1.concat('123')
// "  fex l i x  123"

s1.indexOf('l')
// 6
s1.substring(5)
// " l i x  "
s1.substring(3,9)
// "ex l i"
s1.slice(3,9)
// "ex l i"
s1.substring(-3,9)
// "  fex l i"
s1.slice(-3,9)
// ""
s1.toLocaleLowerCase()
// "  fex l i x  "
s1.toUpperCase()
// "  FEX L I X  "

s1.split(" ")
// (8) ["", "", "fex", "l", "i", "x", "", ""]

s1.split(' ',3)
// (3) ["", "", "fex"]  第2个参数限制返回值个数
示例

 

string.slice(start, stop)和string.substring(start, stop):

两者的相同点:
如果start等于end,返回空字符串
如果stop参数省略,则取到字符串末
如果某个参数超过string的长度,这个参数会被替换为string的长度

substirng()的特点:
如果 start > stop ,start和stop将被交换
如果参数是负数或者不是数字,将会被0替换

silce()的特点:
如果 start > stop 不会交换两者
如果start小于0,则切割从字符串末尾往前数的第abs(start)个的字符开始(包括该位置的字符)
如果stop小于0,则切割在从字符串末尾往前数的第abs(stop)个字符结束(不包含该位置字符)

  

 3.布尔类型(Boolean)

   true和false

  注意: ""(空字符串)、0、null、undefined、NaN都是false。

 

toString() 返回Boolean的字符串值('true'或'false')
toLocaleString() 返回Boolean的字符串值('true'或'false')
valueOf() 返回Boolean的原始布尔值(true或false)
 
4.null和undefined
  • null表示值是空,一般在需要指定或清空一个变量时才会使用,如 name=null;
  • undefined表示当声明一个变量但未初始化时,该变量的默认值是undefined。还有就是函数无明确的返回值时,返回的也是undefined。

  null表示变量的值是空,undefined则表示只声明了变量,但还没有赋值。

  
 5.JS中的对象---数组(Array)
 
var name = Array("felix","alina");
var name = ["felix","alina"];

  常用方法:

Array.length 数组的大小
Array.push() 尾部添加元素
Array.pop() 删除并返回数组的最后一个元素
Array.unshift() 在数组头部插入一个元素
Array.shift( ) 在数组头部移除一个元素
Array.slice( ) 切片
Array.reverse( ) 反转
Array.join( ) 将数组元素连接起来以构建一个字符串
Array.concat( ) 拼接
Array.sort( ) 排序
Array 对数组的内部支持
Array.splice( start, deleteCount, value, ...)

插入、删除或替换数组的元素

obj.splice(n,0,val) 指定位置插入元素
obj.splice(n,1,val) 指定位置替换元素
obj.splice(n,1)    指定位置删除元素
Array.toLocaleString( ) 把数组转换成局部字符串
Array.toString( ) 将数组转换成一个字符串
 
 1 // 数组
 2 var a = [123,'abc',true,'123'];
 3 a
 4 // (4) [123, "abc", true, "123"]
 5 a.length
 6 // 4
 7 a[2]
 8 // true
 9 a.push('abcd')
10 // 5
11 a.pop()
12 // "abcd"
13 a.unshift('AAA')
14 // 5
15 a
16 // (5) ["AAA", 123, "abc", true, "123"]
数组方法示例

  使用.sort()排序需注意:

  如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序。要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较。

  如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下:

  若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。
  若 a 等于 b,则返回 0。
  若 a 大于 b,则返回一个大于 0 的值。

function sortNumber(a,b){
    return a - b
}
var arr1 = [11, 100, 22, 55, 33, 44]
arr1.sort(sortNumber)

 

1 var a = [10, 20, 30, 40];
2 for (var i=0;i<a.length;i++) {
3   console.log(a[i]);
4 }
遍历数组方法

 

6.JS中的对象---“字典”

var obj_dict = {name:'felix',age:18,gender:'boy'}
obj_dict
{name: "felix", age: 18, gender: "boy"}
obj_dict.name
"felix"
obj_dict.age
18
obj_dict["name"]
"felix"

  

7.判断数据类型 typeof

  typeof是一个一元运算符(就像++,--,!,- 等一元运算符),不是一个函数,也不是一个语句。

  对变量或值调用 typeof 运算符将返回下列值之一:

undefined - 如果变量是 Undefined 类型的
boolean - 如果变量是 Boolean 类型的
number - 如果变量是 Number 类型的
string - 如果变量是 String 类型的
object - 如果变量是一种引用类型或 Null 类型的

  

typeof "abc"  // "string"
typeof null  // "object"
typeof true  // "boolean"
typeof 123 // "number"

  

null == undefined
true
typeof null
"object"
list = [1,2,3]
typeof list
"object"

  

typeof "John"                 // 返回 string 
typeof 3.14                   // 返回 number
typeof NaN                    // 返回 number 
typeof false                  // 返回 boolean
typeof [ 1,2,3,4]              // 返回 object
typeof {name: 'John', age:34}  // 返回 object
typeof new Date()             // 返回 object
typeof function () {}         // 返回 function
typeof myCar                  // 返回 undefined (if myCar is not declared) 
typeof null                   // 返回 object

  

三、运算符

1.算数运算符

运算符 含义
+ 加法
- 减法
* 乘法
/ 除法
% 取余
++ 递增1
__ 递减1

 

2.比较运算符

运算符 含义
> 大于
>= 大于等于
< 小于
<= 小于等于
!= 不等于
== 弱等于 如果两个操作值不是同一类型,相等运算符会尝试进行一些类型转换,然后再进行比较
=== 强等于 比较过程没有任何类型转换
!==  严格运算符 ===的结果取反

 

1 == “1”  // true
1 === "1"  // false

  

3.逻辑运算符

运算符 含义
&&
||
!

 

 

4.赋值运算符

   
运算符 含义
= 赋值
+= a+=b 等同于 a = a + b
-= a-=b 等同于 a=a-b
*= a*=b 等同于 a=a*b
/= a/=b 等同于 a=a/b
 
 
 四、流程控制
 1.条件语句
  JavaScript中支持两个条件语句,分别是:if 和 switch。
 
  (1)if else语句
//if语句
 
if(条件){
  
    }else if(条件){
          
    }else{
  
    }

  

 
var a = 10;
if (a > 5){
  console.log("yes");
}else {
  console.log("no");
}

var a = 10;
if (a > 5){
  console.log("a > 5");
}else if (a < 5) {
  console.log("a < 5");
}else {
  console.log("a = 5");
}

  

 (2)switch语句
var day = new Date().getDay();
switch (day) {
  case 0:
  console.log("Sunday");
  break;
  case 1:
  console.log("Monday");
  break;
default:
  console.log("...")
}

  

//switch语句,name等于nick是执行第一个case,等于第二个执行第二个case,其它执行default.

switch(name){
        case 'felix':
            age = 18;
            break;
        case 'alina':
            age = 21;
            break;
        default :
            age = 0;
    }

 

2.循环语句

  JavaScript中支持四种循环语句,分别是:for、for in、while、do-while

  (1)for循环
for (语句 1; 语句 2; 语句 3)
  {
  被执行的代码块
  }

语句 1 在循环(代码块)开始前执行

语句 2 定义运行循环(代码块)的条件

语句 3 在循环(代码块)已被执行之后执行

  

for循环:
    var a = ["123","abc",123,true,false];
    for (var i=0;i<a.length;i++){
        console.log(i);
        console.log(a[i]);
    }

  

   (2)for in循环
    JavaScript for/in 语句循环遍历对象的属性:
for in 循环:
    for (var index in a){
        console.log(index);
        console.log(a[index]);
    }

  

var person={fname:"John",lname:"Doe",age:25};

for (x in person)
  {
  txt=txt + person[x];
  }

  

  (3)while循环

    While 循环会在指定条件为真时循环执行代码块。

while (条件)
  {
  需要执行的代码
  }

  

var age = 18;
while(age < 100) {
    console.log(age);
    age ++;
}

  

  (4)do/while 循环

  do/while 循环是 while 循环的变体。该循环会执行一次代码块,在检查条件是否为真之前,然后如果条件为真的话,就会重复这个循环。

do
  {
  需要执行的代码
  }
while (条件);

  

var x="",i=0;
do
  {
  x=x + "The number is " + i + "<br>";
  i++;
  }
while (i<5)  

 

3.三元运算

var a = 10;
var b = 20;
var c = a > b ? a+b:a-b;

  

4.异常处理
  • try 语句测试代码块的错误。
  • catch 语句处理错误。
  • throw 语句创建自定义错误。
 try
   {
   //在这里运行代码
   }
 catch(err)
   {
   //在这里处理错误
   }

  

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>W3Cschool教程(w3cschool.cn)</title>
<script>
function myFunction(){
    try{ 
        var x=document.getElementById("demo").value;
        if(x=="")    throw "值为空";
        if(isNaN(x)) throw "不是数字";
        if(x>10)     throw "太大";
        if(x<5)      throw "太小";
    }
    catch(err){
        var y=document.getElementById("mess");
        y.innerHTML="错误:" + err + "";
    }
}
</script>
</head>
<body>

<h1>我的第一个 JavaScript</h1>
<p>请输出一个 5 到 10 之间的数字:</p>
<input id="demo" type="text">
<button type="button" onclick="myFunction()">测试输入</button>
<p id="mess"></p>

</body>
</html>
异常处理示例

 

 五、函数

  在JavaScript中,函数即对象,可以随意地被程序操控,函数可以嵌套在其他函数中定义,这样可以访问它们被定义时所处的作用域中的任何变量。

 
 1.JS函数语法
  函数就是包裹在花括号中的代码块,前面使用了关键词 function:
function functionname()
 {
执行代码
 }
 提示:function 中的花括号是必需的,即使函数体内只包含一条语句,仍然必须使用花括号将其括起来。
       JavaScript 对大小写敏感。关键词 function 必须是小写的,并且必须以与函数名称相同的大小写来调用函数。

  

// 普通函数定义
function f1() {
  console.log("Hello world!");
}

// 带参数的函数
function f2(a, b) {
  console.log(arguments);  // 内置的arguments对象
  console.log(arguments.length);
  console.log(a, b);
}

// 带返回值的函数
function sum(a, b){
  return a + b;
}
sum(1, 2);  // 调用函数

// 匿名函数方式
var sum = function(a, b){
  return a + b;
}
sum(1, 2);

// 立即执行函数
(function(a, b){
  return a + b;
})(1, 2);

  

2.函数的调用

(1)直接调用

var age = 18;
function foo(){
  console.log(age);
  var age = 22;
  console.log(age);
  function age(){
    console.log("呵呵");
  }
  console.log(age);
  console.log("=======================================")
}

  

function f2(a,b) {
    console.log('a:',a);
    console.log('b:',b);
    console.log('共有参数:'+ arguments.length + '个');
    var ret = 0;
    for (var i=0;i<arguments.length;i++){
        console.log(i)
        ret += arguments[i]
    }
    return ret
}
var c = 100;
console.log(f2(10,20,30,40,c))

  

 

(2)在连接中调用

  在连接中调用以上函数

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>函数</title>
    <script src="func.js"></script>   //首先从外部导入
</head>
<body>
<a href="javascript:foo()" style="display: block">foo</a> //指定函数名称调用
<a href="javascript:f2(10,20,30)">f2</a>  //指定函数名称调用
</body>
</html>

  

 

 

 

3.函数参数和arguments参数

  函数传参的个数可以小于实际需传参的个数,没传参的默认为undefined

function person(name,age) {
    console.log(name,age)
}

person("felix",18);  //felix 18
person("felix");  //felix undefined
person("felix",18,"boy");  //felix 18

  

   arguments参数:arguments 可接收所有参数,返回一个数组 

function person() {
    console.log(arguments);
    console.log(arguments.length)
}

person('felix');
person('felix',18);
person('felix',18,'gender');
// 执行结果:
// Arguments ["felix", callee: ƒ, Symbol(Symbol.iterator): ƒ]
// 1
// Arguments(2) ["felix", 18, callee: ƒ, Symbol(Symbol.iterator): ƒ]
// 2
// Arguments(3) ["felix", 18, "gender", callee: ƒ, Symbol(Symbol.iterator): ƒ]
// 3

  

function add(a,b){
  console.log(a+b);
  console.log(arguments.length)
}

add(1,2)
执行结果:
3
2

  

4.函数的全局变量和局部变量

局部变量

在JavaScript函数内部声明的变量(使用 var)是局部变量,所以只能在函数内部访问它(该变量的作用域是函数内部)。只要函数运行完毕,本地变量就会被删除。

全局变量:

在函数外声明的变量是全局变量,网页上的所有脚本和函数都能访问它。

变量生存周期:

JavaScript变量的生命期从它们被声明的时间开始。

局部变量会在函数运行以后被删除。

全局变量会在页面关闭后被删除。

 
5.作用域

  首先在函数内部查找变量,找不到则到外层函数查找,逐步找到最外层。

var name = 'felix';
(function person(){
    console.log(name);//undefined
    var name = 'alina';
    console.log(name);//alina
})();
console.log(name);//felix

  

var city = "BeiJing";
function f() {
  var city = "ShangHai";
  function inner(){
    var city = "ShenZhen";
    console.log(city);
  }
  inner();
}

f();  //输出结果是?    ShenZhen


var city = "BeiJing";
function Bar() {
  console.log(city);
}
function f() {
  var city = "ShangHai";
  return Bar;
}
var ret = f();
ret();  // 打印结果是?  BeiJing


//闭包
var city = "BeiJing";
function f(){
    var city = "ShangHai";
    function inner(){
        console.log(city);
    }
    return inner;
}
var ret = f();
ret();  //打印结果?  ShangHai

  

var name = 'nick';
function Main() {
    function F1(){
        var name = 'jenny';
        console.log(name);//jenny
    }
    function F2() {
        console.log(name);//nick
    }
    F1();
    F2();
}
Main();

去掉F1();F2();则打印没有任何输出!

  

function f1(){
  var n=1;
 Add = function(){
  n++;
  };
 function f2(){
    console.log(n);
  }
 return f2;
}
var result=f1();
result(); //1
Add();
result(); //2
//result就是闭包f2函数
//函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除

  

6.词法分析  

  JavaScript代码运行前有一个类似编译的过程即词法分析,词法分析主要有三个步骤:

  • 分析参数
  • 再分析变量的声明
  • 分析函数声明

  具体步骤如下:

  函数在运行的瞬间,生成一个活动对象(Active Object),简称AO

  第一步:分析参数:

  1. 函数接收形式参数,添加到AO的属性,并且这个时候值为undefine,即AO.age=undefine

  2. 接收实参,添加到AO的属性,覆盖之前的undefine

  第二步:分析变量声明:如var age;或var age=18;

  1. 如果上一步分析参数中AO还没有age属性,则添加AO属性为undefine,即AO.age=undefine

  2. 如果AO上面已经有age属性了,则不作任何修改

  第三步:分析函数的声明:

  如果有function age(){}把函数赋给AO.age ,覆盖上一步分析的值

函数1:
var name = "test";
function t() {
    console.log(name);
    var name = "test1";
    console.log(name);
}
t();

函数2:
var name = "test";
function t() {
    console.log(name);
}
t();

词法分析:
0:函数的在运行的瞬间,生成一个活动对象(Active Object)就是所谓的AO

1:分析参数

      1-1:函数接收参数,添加到AO的属性上面,值全部都是undefine,如AO.age=undefine

      1-2:接收实参,形成AO对应的属性值

2:分析变量声明,如var age,

     2-1:如果AO上还没有age属性,则添加AO 属性,值是undefine

     2-2:如果AO 上面已经有了age属性,则不做任何操作。

3:分析函数的声明,如果funcion foo(){},

3-1: 则把函数赋给AO.fooo,如果数据属性已经存在,则要被现在的新的值覆盖

下面开始分析上面修改1的执行的过程(自上崦下):

    1、在window上面形成一个AO链,AO.name=undefine;

    2、在函数的内部分析参数,函数没有参数,略过

    3、在到变量声明阶段,在t函数的内部形成AO1,AO1.name=undfine;

    4、分析函数声明,略过

执行过程:

   1、首先是 在外层的AO.name=”test”

   2、执行t函数,执行到console.log(name)时,函数内有name属性,就不会在到外面去寻找 执行输出undefine

   3、执行赋值语句AO1.name=”test1”

   4、输出当前的name值,”test1”;
示例1

 

function t(age) {
    console.log(age);//1
    var age = 99;
    console.log(age);//2
    function age() {
         
    }
    console.log(age);//3
}
t(5); 
词法分析:
   1-1、分析参数,有一个参数,形成一个AO.age=undefine;
 
   1-2、接收参数AO.age=5;
 
   2、分析变量声明,有一个var age,发现AO上面有一个AO.age,则不做任何处理
 
   3、分析函数声明,有一个function age(){}声明, 则把原有的age覆盖成AO.age=function(){};
 
执行过程
 
   1、执行第一个console.log(age)时,当前的AO.age是一个函数,所以输出的一个函数
 
   2、这句var age=99;是对不AO.age的属性赋值,AO.age=99,所以在第二个输出的是99
 
   3、同理第三个输出的是99,因为中间没有改变age值的语句了,
 
具体结果是,function age(){...},99,99
示例2
 
function t(age) {
    var age;
    console.log(age);
    age = "99";
    console.log(age);
    function age() {
    }
    console.log(age);
}
t(5);
示例3

 

function t(age) {
    var age;
    console.log(age);
    age = "99";
    console.log(age);
    function age() {
        console.log(age);
    }
    age();//这里不一样
    console.log(age);
}
t(5);

分析:
第9行的age()根本不是一个函数,所以执行到这里会报错!!!
示例4

 

 

 

function t(age) {
    var age;
     //age=99;这里被我注释掉了 
    console.log(age);
    function age() {
        console.log(age);
    }
    age();
    console.log(age);
}
t(5);

分析:
这里没有对age的赋值,说明age是一个函数,当这个函数执行的时候,age函数的内部没有age变量,根据作用域链到外层的函数去找,找到了一个age,但它还是一个函数,又再次输出函数,后面一个也是如此,所以结果是下面结果:
示例5

 

 

function t(age) {
    // var age;
    console.log(age);
    var age=function () {
        console.log(age);
    }
    age();
    console.log(age);
}
t(5);

分析:
把表达式拆开也就明白了,拆成如下的结果:var age;age=function(){},也就是函数表达是其实是一个变量声明和赋值的过程,而不是一个真正的函数声明!
示例6

 

 

function t(age) {
    // var age;
    console.log(age);
    var age=function age () {
        console.log(age);
    }
    age();
    console.log(age);
}
t(5);
示例7

 

 

 

六、内置对象和方法

  JavaScript 中的所有事物都是对象:字符串、数值、数组、函数...。此外,JavaScript 允许自定义对象。

1.内置对象介绍

  JavaScript 提供多个内建对象,比如 String、Date、Array 等等。 对象只是带有属性和方法的特殊数据类型。对象只是一种特殊的数据。对象拥有属性方法

  • 布尔型可以是一个对象。
  • 数字型可以是一个对象。
  • 字符串也可以是一个对象
  • 日期是一个对象
  • 数学和正则表达式也是对象
  • 数组是一个对象
  • 甚至函数也可以是对象

 

  注意var s1 = "abc"和var s2 = new String("abc")的区别:typeof s1 --> string而 typeof s2 --> Object

 

2.自定义对象

创建新对象有两种不同的方法:

  • 定义并创建对象的实例
  • 使用函数来定义对象,然后创建新的对象实例

 方法1:创建自定义对象:

person=new Object();
person.firstname="John";
person.lastname="Doe";
person.age=50;
person.eyecolor="blue";

 访问对象的属性:

 

或者直接用声明变量方法创建新对象:

//创建新对象:
var obj_dict = {name:'felix',age:18,gender:'boy'}

//访问属性:
obj_dict
{name: "felix", age: 18, gender: "boy"}
obj_dict.name
"felix"
obj_dict.age
18
obj_dict["name"]
"felix"

  

方法2:首先使用对象构造器创建对象:

function person(firstname,lastname,age,eyecolor)
{
    this.firstname=firstname;
    this.lastname=lastname;
    this.age=age;
    this.eyecolor=eyecolor;
}

 

其次创建js对象实例:

 var myFather=new person("John","Doe",50,"blue");
 var myMother=new person("Sally","Rally",48,"green");

  

再把属性增加到js对象实例中:

通过为对象赋值,向已有对象添加新属性:

 person.firstname="John";
 person.lastname="Doe";
 person.age=30;
 person.eyecolor="blue";  

 

 把方法增加到JS对象:

 
 function person(firstname,lastname,age,eyecolor)
 {
     this.firstname=firstname;
     this.lastname=lastname;
     this.age=age;
     this.eyecolor=eyecolor;

     this.changeName=changeName;
     function changeName(name)
     {
           this.lastname=name;
     }
 }

  changeName() 函数 name 的值赋给 person 的 lastname 属性。

 
myMother.changeName("Doe");

 

3.Date(日期)对象

创建日期对象:

//方法1:不指定参数
var d1 = new Date();
console.log(d1.toLocaleString());
//方法2:参数为日期字符串
var d2 = new Date("2004/3/20 11:12");
console.log(d2.toLocaleString());
var d3 = new Date("04/03/20 11:12");
console.log(d3.toLocaleString());
//方法3:参数为毫秒数
var d3 = new Date(5000);
console.log(d3.toLocaleString());
console.log(d3.toUTCString());

//方法4:参数为年月日小时分钟秒毫秒
var d4 = new Date(2004,2,20,11,12,0,300);
console.log(d4.toLocaleString());  //毫秒并不直接显示

  

Date对象的方法:

var d = new Date(); 
//getDate()                 获取日
//getDay ()                 获取星期
//getMonth ()               获取月(0-11)
//getFullYear ()            获取完整年份
//getHours ()               获取小时
//getMinutes ()             获取分钟
//getSeconds ()             获取秒
//getMilliseconds ()        获取毫秒
//getTime ()                返回累计毫秒数(从1970/1/1午夜)

 

//时间格式化输出
var today = new Date();
var Y = today.getFullYear();
var M = today.getMonth() + 1
var D = today.getDate();
var H = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();

var today_format = Y +'-'+ M + '-' + D + ' ' + H + ':' + m + ':' + s ;
console.log(today_format);

//2019-1-6 13:29:54

  

Date()    返回当日的日期和时间。
getDate()    从 Date 对象返回一个月中的某一天 (1 ~ 31)。
getDay()    从 Date 对象返回一周中的某一天 (0 ~ 6)。
getMonth()    从 Date 对象返回月份 (0 ~ 11)。
getFullYear()    从 Date 对象以四位数字返回年份。
getYear()    请使用 getFullYear() 方法代替。
getHours()    返回 Date 对象的小时 (0 ~ 23)。
getMinutes()    返回 Date 对象的分钟 (0 ~ 59)。
getSeconds()    返回 Date 对象的秒数 (0 ~ 59)。
getMilliseconds()    返回 Date 对象的毫秒(0 ~ 999)。
getTime()    返回 1970 年 1 月 1 日至今的毫秒数。
getTimezoneOffset()    返回本地时间与格林威治标准时间 (GMT) 的分钟差。
getUTCDate()    根据世界时从 Date 对象返回月中的一天 (1 ~ 31)。
getUTCDay()    根据世界时从 Date 对象返回周中的一天 (0 ~ 6)。
getUTCMonth()    根据世界时从 Date 对象返回月份 (0 ~ 11)。
getUTCFullYear()    根据世界时从 Date 对象返回四位数的年份。
getUTCHours()    根据世界时返回 Date 对象的小时 (0 ~ 23)。
getUTCMinutes()    根据世界时返回 Date 对象的分钟 (0 ~ 59)。
getUTCSeconds()    根据世界时返回 Date 对象的秒钟 (0 ~ 59)。
getUTCMilliseconds()    根据世界时返回 Date 对象的毫秒(0 ~ 999)。
parse()    返回1970年1月1日午夜到指定日期(字符串)的毫秒数。
setDate()    设置 Date 对象中月的某一天 (1 ~ 31)。
setMonth()    设置 Date 对象中月份 (0 ~ 11)。
setFullYear()    设置 Date 对象中的年份(四位数字)。
setYear()    请使用 setFullYear() 方法代替。
setHours()    设置 Date 对象中的小时 (0 ~ 23)。
setMinutes()    设置 Date 对象中的分钟 (0 ~ 59)。
setSeconds()    设置 Date 对象中的秒钟 (0 ~ 59)。
setMilliseconds()    设置 Date 对象中的毫秒 (0 ~ 999)。
setTime()    以毫秒设置 Date 对象。
setUTCDate()    根据世界时设置 Date 对象中月份的一天 (1 ~ 31)。
setUTCMonth()    根据世界时设置 Date 对象中的月份 (0 ~ 11)。
setUTCFullYear()    根据世界时设置 Date 对象中的年份(四位数字)。
setUTCHours()    根据世界时设置 Date 对象中的小时 (0 ~ 23)。
setUTCMinutes()    根据世界时设置 Date 对象中的分钟 (0 ~ 59)。
setUTCSeconds()    根据世界时设置 Date 对象中的秒钟 (0 ~ 59)。
setUTCMilliseconds()    根据世界时设置 Date 对象中的毫秒 (0 ~ 999)。
toSource()    返回该对象的源代码。
toString()    把 Date 对象转换为字符串。
toTimeString()    把 Date 对象的时间部分转换为字符串。
toDateString()    把 Date 对象的日期部分转换为字符串。
toGMTString()    请使用 toUTCString() 方法代替。
toUTCString()    根据世界时,把 Date 对象转换为字符串。
toLocaleString()    根据本地时间格式,把 Date 对象转换为字符串。
toLocaleTimeString()    根据本地时间格式,把 Date 对象的时间部分转换为字符串。
toLocaleDateString()    根据本地时间格式,把 Date 对象的日期部分转换为字符串。
UTC()    根据世界时返回 1970 年 1 月 1 日 到指定日期的毫秒数。
valueOf()    返回 Date 对象的原始值。
Date对象方法

 

4.RegExp对象

  正则表达式用于对字符串模式匹配及检索替换,是对字符串执行模式匹配的强大工具。  

(1)语法

var patt=new RegExp(pattern,modifiers);
或者更简单的方式:
var patt=/pattern/modifiers;

说明:
pattern(模式) 描述了表达式的模式
modifiers(修饰符) 用于指定全局匹配、区分大小写的匹配和多行匹配

  

var re = new RegExp("\\w+");
var re = /\w+/;

 

(2)RegExp修饰符

  修饰符用于执行不区分大小写和全文的搜索。

i	执行对大小写不敏感的匹配。
g	执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
m	执行多行匹配。

  

示例1:忽略大小写查找

var str="Welcome to Myhome"; 
var patt1=/myhome/i;

  

示例2:全局查找

var str="Is this all there is?"; 
var patt1=/is/g;

  

示例3:全文查找和不区分大小写搜索 "is"

var str="Is this all there is?"; 
var patt1=/is/gi;

  

(3)方括号和元字符

[abc]    查找方括号之间的任何字符。
[^abc]    查找任何不在方括号之间的字符。
[0-9]    查找任何从 0 至 9 的数字。
[a-z]    查找任何从小写 a 到小写 z 的字符。
[A-Z]    查找任何从大写 A 到大写 Z 的字符。
[A-z]    查找任何从大写 A 到小写 z 的字符。
[adgk]    查找给定集合内的任何字符。
[^adgk]    查找给定集合外的任何字符。
(red|blue|green)    查找任何指定的选项。
方括号
.    查找单个字符,除了换行和行结束符。
\w    查找单词字符。
\W    查找非单词字符。
\d    查找数字。
\D    查找非数字字符。
\s    查找空白字符。
\S    查找非空白字符。
\b    匹配单词边界。
\B    匹配非单词边界。
\0    查找 NUL 字符。
\n    查找换行符。
\f    查找换页符。
\r    查找回车符。
\t    查找制表符。
\v    查找垂直制表符。
\xxx    查找以八进制数 xxx 规定的字符。
\xdd    查找以十六进制数 dd 规定的字符。
\uxxxx    查找以十六进制数 xxxx 规定的 Unicode 字符。
元字符

 

(4)量词

n+    匹配任何包含至少一个 n 的字符串。
n*    匹配任何包含零个或多个 n 的字符串。
n?    匹配任何包含零个或一个 n 的字符串。
n{X}    匹配包含 X 个 n 的序列的字符串。
n{X,Y}    匹配包含 X 至 Y 个 n 的序列的字符串。
n{X,}    匹配包含至少 X 个 n 的序列的字符串。
n$    匹配任何结尾为 n 的字符串。
^n    匹配任何开头为 n 的字符串。
?=n    匹配任何其后紧接指定字符串 n 的字符串。
?!n    匹配任何其后没有紧接指定字符串 n 的字符串。
量词

 

(5)RegExp对象方法

compile    编译正则表达式。
exec    检索字符串中指定的值。返回找到的值,并确定其位置。
test    检索字符串中指定的值。返回 truefalse
对象方法

 

支持正则表达式的String对象方法:

search	检索与正则表达式相匹配的值。
match	找到一个或多个正则表达式的匹配。
replace	替换与正则表达式匹配的子串。
split	把字符串分割为字符串数组。

  

//RegExp对象

//创建正则对象方式1
// 参数1 正则表达式(不能有空格)
// 参数2 匹配模式:常用g(全局匹配;找到所有匹配,而不是在第一个匹配后停止)和i(忽略大小写)

// 用户名只能是英文字母、数字和_,并且首字母必须是英文字母。长度最短不能少于6位 最长不能超过12位。

// 创建RegExp对象方式(逗号后面不要加空格)
var reg1 = new RegExp("^[a-zA-Z][a-zA-Z0-9_]{5,11}$");

// 匹配响应的字符串
var s1 = "bc123";

//RegExp对象的test方法,测试一个字符串是否符合对应的正则规则,返回值是true或false。
reg1.test(s1);  // true

// 创建方式2
// /填写正则表达式/匹配模式(逗号后面不要加空格)
var reg2 = /^[a-zA-Z][a-zA-Z0-9_]{5,11}$/;

reg2.test(s1);  // true


// String对象与正则结合的4个方法
var s2 = "hello world";

s2.match(/o/g);         // ["o", "o"]             查找字符串中 符合正则 的内容
s2.search(/h/g);        // 0                      查找字符串中符合正则表达式的内容位置
s2.split(/o/g);         // ["hell", " w", "rld"]  按照正则表达式对字符串进行切割
s2.replace(/o/g, "s");  // "hells wsrld"          对字符串按照正则进行替换

// 关于匹配模式:g和i的简单示例
var s1 = "name:Alex age:18";

s1.replace(/a/, "哈哈哈");      // "n哈哈哈me:Alex age:18"
s1.replace(/a/g, "哈哈哈");     // "n哈哈哈me:Alex 哈哈哈ge:18"      全局匹配
s1.replace(/a/gi, "哈哈哈");    // "n哈哈哈me:哈哈哈lex 哈哈哈ge:18"  不区分大小写


// 注意事项1:
// 如果regExpObject带有全局标志g,test()函数不是从字符串的开头开始查找,而是从属性regExpObject.lastIndex所指定的索引处开始查找。
// 该属性值默认为0,所以第一次仍然是从字符串的开头查找。
// 当找到一个匹配时,test()函数会将regExpObject.lastIndex的值改为字符串中本次匹配内容的最后一个字符的下一个索引位置。
// 当再次执行test()函数时,将会从该索引位置处开始查找,从而找到下一个匹配。
// 因此,当我们使用test()函数执行了一次匹配之后,如果想要重新使用test()函数从头开始查找,则需要手动将regExpObject.lastIndex的值重置为 0。
// 如果test()函数再也找不到可以匹配的文本时,该函数会自动把regExpObject.lastIndex属性重置为 0。

var reg3 = /foo/g;
// 此时 regex.lastIndex=0
reg3.test('foo'); // 返回true
// 此时 regex.lastIndex=3
reg3.test('xxxfoo'); // 还是返回true
// 所以我们在使用test()方法校验一个字符串是否完全匹配时,一定要加上^和$符号。

// 注意事项2(说出来你可能不信系列):
// 当我们不加参数调用RegExpObj.test()方法时, 相当于执行RegExpObj.test("undefined"), 并且/undefined/.test()默认返回true。
var reg4 = /^undefined$/;
reg4.test(); // 返回true
reg4.test(undefined); // 返回true
reg4.test("undefined"); // 返回true
注意

 

// 坑1 (正则表达式中间一定不可以有空格)
console.log("============================================");
console.log(/^[a-zA-Z][a-zA-Z0-9_]{5,11}$/.test("xiaoqiang"));
console.log(/^[a-zA-Z][a-zA-Z0-9_]{5,11}$/.test("1xiaoqiang"));

// 坑2
// test()不传值相当于传了一个undefined进去
// 然后test()就把这个undefined当成是"undefined"来判断
console.log("============================================");
console.log(/^[a-zA-Z][a-zA-Z0-9_]{5,11}$/.test("undefined"));
console.log(/^[0-9a-zA-Z][a-zA-Z0-9_]{5,11}$/.test());
console.log(/^[0-9][a-zA-Z0-9_]{5,11}$/.test(undefined));
console.log(/^[0-9][a-zA-Z0-9_]{5,11}$/.test("undefined"));

// JS正则的两种模式
// 1. g 表示全局
// 2. i 忽略大小写
var ss = "Alexdashabi";
var s3 = ss.replace(/a/gi, "哈哈哈");  // 不是改变默认的字符串,而是生成了一个新的字符串
console.log(s3);

// 坑3
// 当正则表达式使用了全局模式(g)的时候,并且你还让它去检测一个字符串,此时会引出来一个lastIndex
// lastIndex会记住上一次匹配成功的位置,并把下一次要开始椒盐的位置记住
//
console.log("===============================");
var r = /alex/g;
console.log(r.test("alex"));  // true
console.log(r.lastIndex);  // 4
console.log(r.test("alex"));  // false
console.log(r.lastIndex);
console.log(r.test("alex"));  // true
console.log(r.lastIndex);
console.log(r.test("alex"));  // false
注意“坑”

 

 

5.Math

   Math对象是一个静态对象,而不是构造函数。实际上,Math只是一个由Javascript设置的对象命名空间,用于存储数学函数。

E    返回算术常量 e,即自然对数的底数(约等于2.718)。
LN2    返回 2 的自然对数(约等于0.693)。
LN10    返回 10 的自然对数(约等于2.302)。
LOG2E    返回以 2 为底的 e 的对数(约等于 1.414)。
LOG10E    返回以 10 为底的 e 的对数(约等于0.434)。
PI    返回圆周率(约等于3.14159)。
SQRT1_2    返回返回 2 的平方根的倒数(约等于 0.707)。
SQRT2    返回 2 的平方根(约等于 1.414)。
Math对象属性
abs(x)    返回数的绝对值。
acos(x)    返回数的反余弦值。
asin(x)    返回数的反正弦值。
atan(x)    以介于 -PI/2 与 PI/2 弧度之间的数值来返回 x 的反正切值。
atan2(y,x)    返回从 x 轴到点 (x,y) 的角度(介于 -PI/2 与 PI/2 弧度之间)。
ceil(x)    对数进行上舍入。
cos(x)    返回数的余弦。
exp(x)    返回 e 的指数。
floor(x)    对数进行下舍入。
log(x)    返回数的自然对数(底为e)。
max(x,y)    返回 x 和 y 中的最高值。
min(x,y)    返回 x 和 y 中的最低值。
pow(x,y)    返回 x 的 y 次幂。
random()    返回 0 ~ 1 之间的随机数。
round(x)    把数四舍五入为最接近的整数。
sin(x)    返回数的正弦。
sqrt(x)    返回数的平方根。
tan(x)    返回角的正切。
toSource()    返回该对象的源代码。
valueOf()    返回 Math 对象的原始值
Math对象方法

 

 6.JSON对象

JSON.stringify(obj)   序列化
JSON.parse(str)       反序列化

  

var str1 = '{"name": "Alex", "age": 18}';
var obj1 = {"name": "Alex", "age": 18};
// JSON字符串转换成对象
var obj = JSON.parse(str1); 
// 对象转换成JSON字符串
var str = JSON.stringify(obj1);

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2019-01-02 22:45  %华&仔%  阅读(252)  评论(0编辑  收藏  举报